Você não conhece JS por Kyle Simpson
Tipos e Gramática
1. Tipos Primitivos
Tipos primitivos em JavaScript referem-se aos tipos de dados mais básicos. Existem 6 tipos primitivos:
- Número - Representa números inteiros e de ponto flutuante.
- String - Uma sequência de caracteres cercada por aspas.
- Booleano - Representa valores verdadeiro/falso.
- Indefinido - Uma variável que foi declarada, mas não recebeu um valor.
- Nulo - Representa um não-valor deliberado.
- Símbolo (introduzido no ES6) - Usado para identificadores únicos.
2. Valores e Tipos
No JavaScript, todo valor tem um tipo associado. Quando falamos de tipos, geralmente nos referimos ao tipo de valor ao qual se refere. JavaScript é uma linguagem tipada dinamicamente , o que significa que você não precisa declarar explicitamente o tipo de variável.
Por exemplo:
let example = 42; // Number example = 'Hello'; // Now a String3. Nativos
Nativos são objetos e funções embutidos em JavaScript, como Array, Objeto, Função, etc. Eles fornecem métodos e propriedades que podem ser utilizados para diversas operações.
Exemplo:
let arr = [1, 2, 3]; arr.push(4); // Using native Array method4. Coerção
Coerção é o processo de converter um valor de um tipo para outro. O JavaScript realiza coerção automática, o que pode levar a resultados inesperados.
Exemplo:
'5' + 3; // '53' '5' - 3; // 25. Igualdade
Em JavaScript, a comparação de igualdade pode ser realizada usando == (solto) ou === (estrito). A comparação estrita não realiza coerção de tipo.
Exemplos:
'5' == 5; // true '5' === 5; // false6. Modo Estrito
O Modo Estrito é uma forma de optar por uma variante restrita do JavaScript. Ajuda a detectar erros comuns de codificação e ações 'inseguras', como definir variáveis sem usar var, let ou const.
Para invocar:
'use strict';7. Escopos e Fechamentos
O escopo determina a visibilidade das variáveis. Em JavaScript, temos o escopo da função e o escopo do bloco introduzidos por let e const. Os encerramentos permitem que uma função acesse variáveis de seu escopo pai mesmo depois que a função pai tiver retornado.
8. Içamento
Hoisting é um mecanismo JavaScript onde variáveis e declarações de funções são movidas para o topo de seu escopo de contenção durante a compilação. No entanto, apenas as declarações são elevadas, não as inicializações.
Exemplo:
console.log(x); // undefined var x = 5;9. Escopo a partir de Funções e Blocos
As funções criam seu próprio escopo. Variáveis declaradas dentro de uma função não são acessíveis fora dela. No ES6, o escopo de bloco pode ser criado usando let e const.
10. Funções vs Fechos
Embora as funções sejam blocos de código reutilizáveis, fechamentos permitem que essas funções se lembrem do ambiente em que foram criadas. Isso é fundamental na programação funcional.
11. Funções Imediatas
Também conhecido como IIFE (Immediate Invoked Function Expression), é uma função que executa assim que é definida. Isso é útil para criar um escopo local.
(function() { console.log('I execute right away!'); })();12. Módulos
Módulos permitem que desenvolvedores dividam o código em arquivos separados, seguindo o padrão do módulo. Eles aumentam a manutenção e a reutilização.
13. Esta palavra-chave
Essa palavra-chave refere-se ao objeto ao qual ela pertence. Seu valor pode variar dependendo de como uma função é chamada. Ele pode apontar para diferentes objetos em diferentes contextos.
14. Protótipos
Todo objeto JavaScript tem um protótipo. Protótipos permitem a herança de propriedades e métodos. Ao tentar acessar uma propriedade, o JavaScript verifica o objeto e depois sua cadeia de protótipo.
15. Objetos e Propriedades
Objetos são coleções de propriedades. Cada propriedade possui uma chave e um valor. Ao trabalhar com objetos, é comum usar notação de pontos ou colchete quadrado para acessar propriedades.
let obj = {key: 'value'}; console.log(obj.key); // 'value'16. Mixinas e Herança
Mixins permitem o compartilhamento de métodos entre diferentes objetos. Isso contrasta com a herança de classe, onde uma subclasse deriva de uma classe mãe. A mistura pode facilitar o reuso do código sem seguir estritamente uma hierarquia de classes.
17. Estático vs Não Estático
Métodos estáticos pertencem à própria classe, e não às instâncias da classe. Eles podem ser chamados na própria classe sem ser instanciados. Métodos não estáticos, por outro lado, são chamados em instâncias.
18. Classes e subclasses ES6
O ES6 introduziu uma sintaxe mais limpa para classes para aprimorar a herança baseada em protótipo. A subclasse permite criar classes derivadas com construtores e métodos.
19. Tipo de Dado de Símbolo
Símbolos são um tipo de dado único e imutável introduzido no ES6 que pode ser usado como chaves de propriedade de objetos. Eles ajudam a evitar conflitos de nomes entre propriedades em objetos.
const sym = Symbol('description');20. Depuração com Tipos
Entender os tipos pode ajudar na depuração. Use typeof para verificar os tipos de variáveis. Isso evita erros comuns que ocorrem devido à coerção ou descompasso de tipo.
21. Construtores de Funções
Construtores de funções permitem criar múltiplas instâncias de um objeto usando novas. Elas funcionam como classes para criar instâncias de objetos com propriedades compartilhadas de protótipo.
function Person(name) { this.name = name; } let person1 = new Person('John');22. Primitivo vs Objeto
Valores primitivos são imutáveis e copiados por valor, enquanto objetos são mutáveis e copiados por referência. Essa diferença influencia como eles se comportam em missões e operações.
23. Polyfills
Polyfills são scripts que permitem o uso de recursos mais recentes em ambientes JavaScript mais antigos. Eles ajudam a garantir a compatibilidade entre várias versões de navegadores web.
24. Dicas de Desempenho
Para melhorar o desempenho, prefira valores primitivos em vez de objetos, evite variáveis globais e armazene em cache chamadas de função caras. Compreender o impacto dos tipos e valores no desempenho é fundamental.
25. Gerenciamento de memória
O JavaScript lida automaticamente com a memória. No entanto, entender como as referências funcionam pode ajudar a evitar vazamentos de memória e otimizar o desempenho. É importante anular referências a objetos que não são mais necessários.
26. Dicas Pragmáticas para Escrever Código Melhor
Foque na clareza, evite expressões complexas e aproveite recursos do ES6 como funções de seta e desestruturação para uma sintaxe mais limpa. Escreva comentários para explicar a lógica difícil.
27. Análise Automatizada de Uso
Utilize ferramentas para analisar padrões de uso de código. Automatizar esse processo ajuda a identificar variáveis e funções não utilizadas, levando a um código mais limpo e eficiente.
28. TypeScript e Flow
TypeScript e Flow são ferramentas que adicionam tipagem estática ao JavaScript, ajudando a detectar erros de tipo durante o desenvolvimento, em vez de em tempo de execução. Eles aumentam a robustez das aplicações JavaScript.
29. Técnicas Combinadas
Utilize uma combinação das técnicas acima para obter a qualidade ideal do código. Combinar programação funcional com POO (Programação Orientada a Objetos) pode levar a um código mais fácil de manter e reutilizável.
Escopo & Fechamentos
Introdução ao Escopo
Em JavaScript, escopo refere-se à acessibilidade de variáveis e funções. Ela determina a visibilidade e a vida útil das variáveis em um programa. Compreender o escopo é vital para uma programação JavaScript eficaz.
Tipos de Escopo
Existem dois tipos principais de escopo no JavaScript:
- Escopo Global: Variáveis declaradas fora de qualquer função ou bloco estão no escopo global, acessíveis de qualquer lugar do código.
- Escopo Local: Variáveis declaradas dentro de uma função estão no escopo local, acessíveis apenas dentro dessa função.
Escopo Lexical
Escopo lexical refere-se à capacidade de uma função de acessar variáveis de seu escopo externo (pai), com base em onde foi definida, e não onde foi chamada. Esse princípio é crucial para entender os fechamentos.
O que são Closures?
Um encerramento é uma função que mantém o acesso ao seu escopo lexical, mesmo quando a função é executada fora desse escopo. Os encerramentos permitem o encapsulamento de dados e podem levar a padrões de programação poderosos.
Criando um encerramento
Para criar um fechamento, defina uma função dentro de outra função:
function outer() { let outerVar = 'Hello'; function inner() { console.log(outerVar); } return inner; }Aqui, a
innerfunção forma um fechamento que captura o valor deouterVar.Encerramentos na prática
Os encerramentos fornecem uma maneira de manter o estado de maneira funcional. Por exemplo, você pode criar uma fábrica de funções:
function makeCounter() { let count = 0; return function() { count += 1; return count; }; }Essa
makeCounterfunção usa um fechamento para manter acountvariável.Módulos e Fechamentos
Os encerramentos podem ser usados para criar variáveis privadas, formando módulos de forma eficaz. Isso permite que parte do seu código seja encapsulado e ocultado do escopo global:
const module = (function() { let privateVar = 'I am private'; return { getPrivateVar: () => privateVar }; })();Aqui,
privateVarnão pode ser acessado de fora do módulo.Melhores Práticas para Gestão de Escopo
Para gerenciar o escopo de forma eficaz, considere as seguintes melhores práticas:
- Use
leteconstdeclare variáveis com escopo de bloco. - Evite variáveis globais para evitar conflitos e comportamentos não intencionais.
- Encapsular variáveis e funções dentro dos fechamentos para melhorar a manutenibilidade.
- Use
Entendendo 'isto', Vinculação 'isto', Protótipos de Objetos, Delegação de Comportamento e a palavra-chave 'nova'
Entendendo 'isso'
'isto' em JavaScript pode ser um conceito confuso para muitos desenvolvedores. Diferente de muitas outras linguagens de programação, 'isto' não se refere ao objeto atual, mas sim ao contexto em que uma função é executada. Em outras palavras, seu valor pode mudar dependendo de como uma função é chamada.
O valor de 'isto' é determinado em tempo de execução, não em tempo de análise, o que significa que você precisa ter cuidado com a forma como as funções são invocadas para garantir que 'isso' aponte ao que você espera.
Encadernando 'isto'
O JavaScript fornece vários mecanismos para vincular 'isto'. Os métodos mais comuns são:
- Invocação de Função: Quando uma função é chamada como uma função independente, 'isto' é o padrão para o objeto global (ou indefinido no modo estrito).
- Invocação de Método: Quando uma função é chamada como método de um objeto, 'isto' está vinculado a esse objeto.
- Invocação do Construtor: Quando uma função é invocada com a palavra-chave 'nova', 'isto' é vinculado ao objeto recém-criado.
- Vinculação Explícita: Usar 'chamar', 'aplicar' ou 'vincular' permite controle explícito sobre o que 'isto' se refere.
Protótipos de Objetos
No JavaScript, todo objeto tem um link interno para outro objeto chamado seu protótipo. Esse mecanismo permite que objetos herdem propriedades e métodos de seu protótipo. O protótipo de um objeto pode ser encontrado usando
Object.getPrototypeOf(obj)ou a__proto__propriedade.Objetos herdam propriedades e métodos através da cadeia do protótipo. Portanto, ao tentar acessar uma propriedade, se o objeto não a possui diretamente, o JavaScript verifica o protótipo do objeto e continua subindo na cadeia.
Delegação de Comportamento
Delegação de comportamento é um padrão de design que aproveita a cadeia de protótipos. Em vez de cada objeto ter suas próprias cópias de métodos, múltiplos objetos podem compartilhar métodos definidos em seus protótipos. Isso pode levar a um uso da memória mais eficiente, bem como a uma estrutura limpa e organizada.
Por exemplo, definir métodos no protótipo de um construtor e criar instâncias desse construtor permite que essas instâncias compartilhem os mesmos métodos, o que pode facilitar a reutilização do código.
A palavra-chave 'nova'
A palavra-chave 'new' é usada para criar uma instância de um objeto a partir de uma função construtora. Quando uma função é invocada com 'nova', ocorre o seguinte:
- Um novo objeto é criado.
- O contexto da
thisfunção é definido para esse novo objeto. - O novo objeto está vinculado ao protótipo do construtor.
- A função construtora retorna o novo objeto, a menos que ela retorne explicitamente um objeto diferente.
Isso é crucial para alcançar programação orientada a objetos em JavaScript.
Assíncrono & Performance
Entendendo JavaScript Assíncrono
O JavaScript assíncrono permite que operações sejam executadas em segundo plano, melhorando a resposta da aplicação. O JavaScript alcança isso por meio de um loop de eventos de thread única , que gerencia tarefas e execução de forma não bloqueadora.
O Loop de Eventos
O ciclo de eventos desempenha um papel crucial no gerenciamento de tarefas assíncronas. Ele verifica a fila de mensagens para tarefas, as executa se estiverem prontas e continua esse ciclo. Isso significa que seu código permanece responsivo, mesmo enquanto espera por operações de longa duração.
Técnicas de Otimização de Desempenho
- Debouncing: Limite a taxa com que uma função é invocada para melhorar o desempenho.
- Limitação: Controle com que frequência uma função pode ser executada ao longo do tempo.
- Carregamento Preguiçoso: Atrase o carregamento dos recursos até que sejam necessários.
- Trabalhadores da Web: Execute scripts em threads em segundo plano para cálculos intensos.
Promessas
As promessas oferecem uma forma mais limpa de lidar com operações assíncronas em comparação com callbacks. Eles representam um valor que pode estar disponível agora, ou no futuro, ou nunca. O encadeamento de promessas permite um tratamento e sequenciamento de erros mais limpos das tarefas assíncronas.
Geradores
Geradores permitem que funções forneçam múltiplos valores ao longo do tempo, pausando a execução e retomando depois. Isso os torna úteis para lidar com operações assíncronas em fluxos de código tradicionais. Eles podem ser combinados com Promises para melhor gerenciamento da lógica assíncrona.
Async/Await
Async/Await simplifica o trabalho com Promises, tornando o código mais fácil de ler e raciocinar. Ao marcar uma função como assíncrona, você pode usar await para pausar a execução até que uma Promessa seja resolvida, efetivamente escrevendo código assíncrono que parece síncrono.
ES6 e além
Introdução ao ES6
ECMAScript 6, também conhecido como ES6 ou ES2015, trouxe melhorias significativas ao JavaScript que aprimoram o desenvolvimento e a manutenibilidade. Como Kyle Simpson observa, isso ajuda a tornar o código mais legível e expressivo.
Variáveis com escopo de bloco
Uma das funcionalidades mais significativas introduzidas no ES6 são as palavras-chave let e const , permitindo definições de variáveis com escopo de bloco. Ao contrário do var, que é escopado por funções, seja e const respeitam os limites de bloco.
- let: Permite declarar variáveis que são limitadas ao escopo de um bloco.
- const: Declara variáveis cujos valores não devem mudar.
Funções de Flecha
As funções de seta fornecem uma sintaxe mais concisa para escrever expressões de funções. Eles também vinculam lexicamente esse valor, tornando-os particularmente úteis em certos contextos.
const add = (a, b) => a + b;Literais Template
Literais template simplificam a interpolação de strings e as strings de múltiplas linhas. Em vez de concatenar strings, você pode usar backticks e embeds expressions.
const name = 'World'; const greeting = `Hello, ${name}!`;Tarefa de Desestruturação
Esse recurso do ES6 permite desempacotar valores de arrays ou propriedades de objetos em variáveis distintas, melhorando a legibilidade.
const person = { name: 'John', age: 30 }; const { name, age } = person;Promessas
Promessas representam a eventual conclusão (ou falha) de uma operação assíncrona. Eles permitem um encadenamento e tratamento de erros mais fáceis em comparação com as funções tradicionais de retorno de chamada.
let myPromise = new Promise((resolve, reject) => { /*...*/ });Classes
O ES6 introduziu uma sintaxe de classes mais familiar para JavaScript, o que facilita para quem vem de linguagens baseadas em classes. No entanto, é importante lembrar que esses são açúcar sintático em relação aos protótipos existentes.
class Animal { constructor(name) { this.name = name; } }Módulos
O ES6 oferece um sistema nativo de módulos, permitindo que desenvolvedores escrevam código modular e reutilizável. Você pode facilmente exportar e importar funções, objetos ou primitivas entre arquivos.
export const myFunc = () => { /*...*/ };Operadores de Spread e Rest
Introduzidos no ES6, os parâmetros de espalhamento (...) e repouso permitem um tratamento mais intuitivo dos argumentos de funções e manipulação de arrays.
- Operador de Espalhamento: Achata arrays ou espalha propriedades de objetos.
- Parâmetro de Repouso (Parâmetro de Repoju): Reúne os argumentos restantes em um arranjo.
Versões futuras
Embora este capítulo tenha se concentrado no ES6, é importante manter-se informado sobre futuras propostas de ECMAScript, como estruturas de dados assíncronas/await, mapeadas e definidas. Esses recursos levam o JavaScript aos padrões modernos e melhoram a experiência geral do desenvolvedor.
Em JavaScript
Origens do JavaScript
O JavaScript foi desenvolvido no início dos anos 1990 por Brendan Eich na Netscape. Originalmente destinada a adicionar interatividade às páginas web, desde então evoluiu para uma linguagem de programação versátil e poderosa.
Características do JavaScript
JavaScript é:
- Dinâmica: JavaScript suporta tipagem dinâmica, ou seja, variáveis podem conter valores de qualquer tipo.
- Baseado em Protótipos: Ao contrário da herança clássica, o JavaScript usa protótipos para herança.
- Funções de Primeira Classe: Funções em JavaScript podem ser armazenadas em variáveis, passadas como argumentos e retornadas de outras funções.
Características únicas
O poder do JavaScript está em seu design exclusivo:
- Programação assíncrona: O JavaScript se destaca no tratamento de eventos assíncronos, permitindo operações sem bloqueio.
- Orientado a eventos: O JavaScript responde às ações e eventos do usuário, tornando-o perfeito para aplicativos da Web interativos.
Conceitos Fundamentais
Compreender os conceitos centrais é crucial ao mergulhar em JavaScript:
- Variáveis: Contêineres para armazenar valores de dados.
- Funções: Blocos de código projetados para realizar uma tarefa específica.
- Objetos: Coleções de propriedades, organizadas em pares-chave-valor.
Dicas e Truques
Para dominar JavaScript, abrace suas peculiaridades e aprenda suas melhores práticas:
- Sempre use 'let' ou 'const': Isso ajuda a evitar problemas de içamento e deixa seu telescópio claro.
- Entenda 'isso': Entenda como o contexto muda seu valor com base em como as funções são chamadas.