Dev NotesJS

JavaScript ES6+

JavaScript ES6+ introduziu várias melhorias e recursos que tornam o código mais conciso e legível. Esses recursos incluem let e const, template literals, destructuring, arrow functions, promises e async/await.


Bases do ES6+

JavaScript ES6+ é a versão mais recente do JavaScript, que introduziu várias melhorias e recursos que tornam o código mais conciso e legível. Esses recursos incluem let e const, template literals, destructuring, arrow functions, promises e async/await, entre outros.

Exemplo:

1let x = 5; 2const y = 6; 3 4console.log(`x: ${x}, y: ${y}`); 5// x: 5, y: 6 6 7let person = {name: 'Diana', job: 'Developer'}; 8let {name, job} = person; 9 10console.log(`Name: ${name}, Job: ${job}`); 11// Name: Diana, Job: Developer 12 13let add = (x, y) => x + y; 14console.log(add(5, 6)); 15// 11 16 17let promise = new Promise((resolve, reject) => { 18 setTimeout(() => { 19 resolve('Success'); 20 }, 1000); 21}); 22 23promise.then(result => { 24 console.log(result); 25}); 26// Success 27 28async function fetchData() { 29 let response = await fetch('https://api.example.com/data'); 30 let data = await response.json(); 31 console.log(data); 32} 33 34fetchData(); 35// Dados da API
No exemplo acima, x é uma variável declarada com let e y é uma constante declarada com const. As template literals são usadas para interpolar variáveis dentro de strings usando crase (`). A desestruturação é usada para extrair valores de um objeto diretamente em variáveis. As arrow functions são usadas para definir funções de forma mais concisa. As promises são usadas para lidar com operações assíncronas, permitindo que você execute código quando a operação for concluída. A palavra-chave async é usada para definir uma função assíncrona, e await é usado para esperar a resolução de uma promise.

Diferenças entre let, const e var

As palavras-chave let, const e var são usadas para declarar variáveis em JavaScript. A principal diferença entre elas é o escopo e a mutabilidade.

Exemplo:

1var x = 5; // Escopo global ou de função 2let y = 6; // Escopo de bloco 3const z = 7; // Escopo de bloco e imutável 4 5x = 10; // Válido 6// y = 20; // Válido, pois let permite reatribuição 7// z = 30; // Inválido, pois const não permite reatribuição
No exemplo acima, x é uma variável declarada com var, que tem escopo global ou de função. y é uma variável declarada com let, que tem escopo de bloco e permite reatribuição. z é uma constante declarada com const, que também tem escopo de bloco, mas é imutável e não permite reatribuição.

Escopo global, de bloco e de função

O escopo determina onde uma variável pode ser acessada no código. Em JavaScript, existem três tipos principais de escopo: global, de bloco e de função.

Exemplo:

1var globalVar = 'I am global'; // Escopo global 2 3function myFunction() { 4 var functionVar = 'I am local to this function'; // Escopo de função 5 if (true) { 6 let blockVar = 'I am local to this block'; // Escopo de bloco 7 console.log(blockVar); // I am local to this block 8 } 9 // console.log(blockVar); // Inválido, blockVar não está acessível aqui 10 console.log(functionVar); // I am local to this function 11} 12 13myFunction(); 14console.log(globalVar); // I am global 15// console.log(functionVar); // Inválido, functionVar não está acessível aqui
No exemplo acima, globalVar é uma variável com escopo global, acessível em qualquer lugar do código. functionVar é uma variável com escopo de função, acessível apenas dentro da função myFunction. blockVar é uma variável com escopo de bloco, acessível apenas dentro do bloco onde foi declarada. Tentar acessar blockVar fora do bloco resultará em um erro, assim como tentar acessar functionVar fora da função.

Imutabilidade com const

A palavra-chave const é usada para declarar constantes, que são variáveis cujo valor não pode ser reatribuído após a declaração. No entanto, se a constante for um objeto ou vetor, suas propriedades ou elementos ainda podem ser modificados.

Exemplo:

1const person = {name: 'Diana', job: 'Developer'}; 2 3// person = {name: 'Alice'}; // Inválido, não é possível reatribuir uma constante 4person.name = 'Alice'; // Válido, é possível modificar propriedades 5console.log(person.name); // Alice 6 7const numbers = [1, 2, 3]; 8 9// numbers = [4, 5, 6]; // Inválido, não é possível reatribuir uma constante 10numbers.push(4); // Válido, é possível modificar o vetor 11console.log(numbers); // [1, 2, 3, 4]
No exemplo acima, person é uma constante que armazena um objeto. Tentar reatribuir person resultará em um erro, mas é possível modificar suas propriedades. O mesmo se aplica ao vetor numbers, que é uma constante, mas seus elementos podem ser modificados. A imutabilidade com const se refere à impossibilidade de reatribuir a variável, não de modificar seus conteúdos se for um objeto ou vetor.

Arrow Functions e this

Arrow functions são uma forma concisa de escrever funções em JavaScript. Elas não têm seu próprio contexto de this, o que significa que o valor de this dentro de uma arrow function é o mesmo que o valor de this no escopo onde a função foi definida.

Exemplo:

1const person = { 2 name: 'Diana', 3 greet: function() { 4 setTimeout(() => { 5 console.log(`Hello, ${this.name}!`); 6 }, 1000); 7 } 8}; 9 10person.greet(); // Hello, Diana! (após 1 segundo)
No exemplo acima, person é um objeto com uma função greet que usa uma arrow function dentro de setTimeout. A arrow function não tem seu próprio contexto de this, então ela herda o valor de this do objeto person, permitindo acessar a propriedade name corretamente.

Template Literals e desestruturação

Template literals são strings que permitem interpolação de variáveis e expressões. A desestruturação é uma maneira de extrair valores de objetos e vetores de forma mais concisa.

Exemplo:

1let name = 'Diana'; 2let job = 'Developer'; 3 4console.log(`Name: ${name}, Job: ${job}`); 5// Name: Diana, Job: Developer 6 7let person = {name: 'Diana', job: 'Developer'}; 8let {name, job} = person; 9 10console.log(`Name: ${name}, Job: ${job}`); 11// Name: Diana, Job: Developer
No exemplo acima, as template literals são usadas para interpolar variáveis dentro de strings usando crase (`). A desestruturação é usada para extrair valores de um objeto diretamente em variáveis. Isso torna o código mais conciso e legível.

Interpolação de strings

A interpolação de strings permite inserir variáveis e expressões dentro de strings usando template literals. Isso facilita a criação de strings dinâmicas.

Exemplo:

1let name = 'Diana'; 2let job = 'Developer'; 3 4console.log(`Name: ${name}, Job: ${job}`); 5// Name: Diana, Job: Developer
No exemplo acima, as variáveis name e job são interpoladas dentro de uma string usando template literals. Isso permite criar strings dinâmicas de forma mais fácil e legível.

String em múltiplas linhas

Template literals permitem criar strings em múltiplas linhas sem a necessidade de concatenar várias strings ou usar caracteres especiais. Isso torna o código mais legível e organizado.

Exemplo:

1let message = `Hello, 2This is a message 3in multiple lines.`; 4 5console.log(message); 6// Hello, 7// This is a message 8// in multiple lines.
No exemplo acima, a string message é definida usando template literals, permitindo que ela ocupe várias linhas sem a necessidade de concatenar strings ou usar caracteres especiais. Isso torna o código mais legível e organizado.

Desestruturação de objetos e vetores

A desestruturação permite extrair valores de objetos e vetores de forma mais concisa. Isso facilita a atribuição de valores a variáveis sem a necessidade de acessar cada propriedade individualmente.

Exemplo:

1let person = {name: 'Diana', job: 'Developer'}; 2let {name, job} = person; 3 4console.log(`Name: ${name}, Job: ${job}`); 5// Name: Diana, Job: Developer 6 7let fruits = ['apple', 'banana', 'cherry']; 8let [first, second] = fruits; 9 10console.log(`First fruit: ${first}, Second fruit: ${second}`); 11// First fruit: apple, Second fruit: banana
No exemplo acima, a desestruturação é usada para extrair valores de um objeto e um vetor diretamente em variáveis. Isso torna o código mais conciso e legível, evitando a necessidade de acessar cada propriedade ou elemento individualmente.

Desestruturação de objetos, renomeando variáveis

A desestruturação de objetos permite renomear variáveis ao extrair valores de um objeto. Isso é útil quando você deseja usar nomes de variáveis diferentes dos nomes das propriedades do objeto.

Exemplo:

1let person = {name: 'Diana', job: 'Developer'}; 2let {name: fullName, job: occupation} = person; 3 4console.log(`Full Name: ${fullName}, Occupation: ${occupation}`); 5// Full Name: Diana, Occupation: Developer
No exemplo acima, a desestruturação é usada para extrair valores de um objeto e renomear as variáveis ao mesmo tempo. As propriedades name e job são extraídas e renomeadas para fullName e occupation, respectivamente. Isso permite usar nomes de variáveis mais significativos ou evitar conflitos de nomes.

Desestruturação de vetores, pulando elementos

A desestruturação de vetores permite extrair valores de um vetor e pular elementos indesejados. Isso é útil quando você deseja extrair apenas alguns elementos de um vetor sem precisar acessar cada um individualmente.

Exemplo:

1let fruits = ['apple', 'banana', 'cherry', 'date']; 2let [first, , third] = fruits; 3 4console.log(`First fruit: ${first}, Third fruit: ${third}`); 5// First fruit: apple, Third fruit: cherry
No exemplo acima, a desestruturação é usada para extrair o primeiro e o terceiro elemento de um vetor, pulando o segundo elemento. Isso permite extrair apenas os elementos desejados sem precisar acessar cada um individualmente.

Desestruturação de vetores, restando elementos

A desestruturação de vetores com o operador rest permite extrair todos os elementos restantes de um vetor em uma nova variável. Isso é útil quando você deseja capturar todos os elementos restantes de um vetor após extrair alguns elementos específicos.

Exemplo:

1let fruits = ['apple', 'banana', 'cherry', 'date']; 2let [first, second, ...rest] = fruits; 3 4console.log(`First fruit: ${first}, Second fruit: ${second}`); 5// First fruit: apple, Second fruit: banana 6console.log(`Rest of the fruits: ${rest}`); 7// Rest of the fruits: cherry,date
No exemplo acima, a desestruturação é usada para extrair o primeiro e o segundo elemento de um vetor, enquanto todos os elementos restantes são capturados na variável rest. Isso permite trabalhar com os elementos restantes de forma mais conveniente, sem precisar acessar cada um individualmente.

Desestruturação de objetos aninhados

A desestruturação de objetos aninhados permite extrair valores de objetos que estão dentro de outros objetos. Isso é útil quando você trabalha com estruturas de dados complexas.

Exemplo:

1let person = { 2 name: 'Diana', 3 job: { 4 title: 'Developer', 5 experience: 5 6 } 7}; 8let {name, job: {title, experience}} = person; 9 10console.log(`Name: ${name}, Job Title: ${title}, Experience: ${experience} years`); 11// Name: Diana, Job Title: Developer, Experience: 5 years
No exemplo acima, a desestruturação é usada para extrair valores de um objeto aninhado. As propriedades name, title e experience são extraídas diretamente em variáveis, permitindo acessar facilmente os valores de objetos complexos.

Desestruturação de vetores aninhados

A desestruturação de vetores aninhados permite extrair valores de vetores que estão dentro de outros vetores. Isso é útil quando você trabalha com estruturas de dados complexas.

Exemplo:

1let fruits = [['apple', 'banana'], ['cherry', 'date']]; 2let [[firstFruit, secondFruit], [thirdFruit, fourthFruit]] = fruits; 3 4console.log(`First Fruit: ${firstFruit}, Second Fruit: ${secondFruit}`); 5// First Fruit: apple, Second Fruit: banana 6console.log(`Third Fruit: ${thirdFruit}, Fourth Fruit: ${fourthFruit}`); 7// Third Fruit: cherry, Fourth Fruit: date
No exemplo acima, a desestruturação é usada para extrair valores de um vetor aninhado. Os elementos dos vetores internos são extraídos diretamente em variáveis, permitindo acessar facilmente os valores de estruturas de dados complexas.