Escopo no nível do bloco
O ES5 não possui escopo no nível do bloco, apenas escopo global e escopo da função. Devido a isso, o escopo das variáveis é muito amplo; portanto, você deve criá -lo imediatamente assim que entrar na função. Isso causa o chamado aumento variável.
O recurso "Melhoria da variável" do ES5 geralmente causa um erro se você não tomar cuidado:
1. A variável interna cobre a variável externa
var tmp = new date (); função f () {console.log (tmp); if (false) {// execute undefinedvar tmp = "hello world";}}2. Vazes variáveis para variáveis globais
var s = 'hello'; para (var i = 0; i <s.length; i ++) {console.log (s [i]);} console.log (i); // 5No passado, costumamos usar o fechamento para resolver esse problema (como funções auto-executivas). Agora, com base nesse problema, o ES6 adicionou escopo no nível do bloco, portanto, não há necessidade de executar funções por si só.
deixe e const
O ES6 é compatível com versões anteriores e manter a compatibilidade com versões anteriores significa que nunca muda o comportamento do código JS na plataforma da Web; portanto, o escopo das variáveis criadas pelo VAR ainda será o escopo e o escopo da função global. Dessa forma, mesmo se você tiver um escopo em nível de bloco, ele não pode resolver o problema de "melhoramento variável" do ES5. Portanto, aqui o ES6 adicionou duas novas palavras -chave: Let e Const.
1.Let
"Let é um VAR mais perfeito", possui melhores regras de escopo.
2.CONT
Const declara uma constante somente leitura. Uma vez declarado, o valor da constante não pode ser alterado, mas o objeto declarado pela const pode ter alterações na propriedade (objeto de congelamento do objeto.Freeze)
const a = []; a.push ('hello'); // executável a = ['Dave']; // Relate um erroVocê também pode usar object.Freeze para congelar o objeto
const foo = object.freeze ({}); // No modo normal, a linha a seguir não funciona; // No modo rigoroso, a linha relatará um erro foo.prop = 123; //Use Let and Const:
• Variáveis são válidas apenas dentro do escopo do nível de bloco, onde a declaração está localizada
• A declaração variável só pode ser usada (zona morta temporária)
• Variáveis não podem ser definidas repetidamente
• A variável global declarada, atributos que não pertencem a objetos globais
var a = 1; janela.
Essa palavra -chave
Sabemos que isso na função ES5 aponta para o escopo em que o tempo de execução está localizado. por exemplo
function foo () {setTimeout (function () {console.log ('id:', this.id);}, 100);} var id = 21; foo.call ({id: 42}); // id: 21Aqui, eu declaro uma função Foo, que é internamente uma função de atraso Settimeout, imprimindo um. Chamamos isso através do foo.call ({id: 42}) e definimos o escopo para esta função. São necessários 100 milissegundos para realmente executar. Como isso aponta para o escopo em que o tempo de execução está localizado, isso aqui aponta para a janela Global Object, não a função Foo. aqui:
• Use a chamada para alterar o contexto de execução do foo, para que o contexto de execução da função não seja mais janela, de modo a distinguir esse ponteiro no setTimeout
• O método Settimeout é pendurado sob o objeto da janela, portanto, isso aponta para o escopo da execução - o objeto da janela.
O código chamado Timeout é executado no escopo global; portanto, o valor disso na função aponta para o objeto de janela no modo não rigoroso e é indefinido no modo rigoroso-《JavaScript Programa Avançado》》
Para resolver esse problema, nossa prática usual é atribuir isso a outras variáveis:
function foo () {var that = this; setTimeout (function () {console.log ('id:', that.id);}, 100);} var id = 21; foo.call ({id: 42}); // id: 42Agora o ES6 lançou a função de seta para resolver esse problema.
Função de seta
Identificador => expressão
var sum = (num1, num2) => {return num1 + num2; } // equivalente a var sum = function (num1, num2) {return num1 + num2;};• Se a função tiver apenas um parâmetro, parênteses poderão ser omitidos
• Se a função tiver apenas uma declaração de retorno, aparelhos e retorno podem ser omitidos
• Se a função retornar um objeto diretamente, os parênteses deverão ser adicionados fora do objeto. (Porque um objeto vazio {} e um bloco vazio {} parecem exatamente iguais. Então você precisa envolver os literais do objeto em colchetes.)
Em resposta ao problema dessa palavra -chave, o ES6 especifica o escopo em que essa ligação é definida na função de seta, em vez de apontar para o escopo em que o tempo de execução está localizado. Desde esse ponto, esse ponto foi corrigido, o que é propício para encapsular funções de retorno de chamada.
function foo () {var that = this; setTimeout (() => {console.log ('id:', that.id);}, 100);} var id = 21; foo.call ({id: 42}); // id: 42Nota: A fixação apontando para a função de seta não é porque existe um mecanismo para ligar isso dentro da função de seta. A razão real é que a função de seta não possui essa por conta própria. A função de seta não tem sua própria, e a interna é isso no bloco de código externo. Isso leva a:
• Não pode ser usado como construtor
• Você não pode usar Call (), Aplicar (), Bind () e outros métodos para alterar a direção deste
Classes e herança
O ECMAScript tradicional não tem o conceito de classes. Ele descreve o conceito de cadeias de protótipo e usa cadeias de protótipo como o principal método para implementar a herança. A idéia básica é usar protótipos para permitir um tipo de referência para herdar as propriedades e métodos de outro tipo de referência. A maneira tradicional de alcançar esse comportamento é através do construtor:
ponto de função (x, y) {this.x = x; this.y = y;} Point.prototype.ToString = function () {return '(' + this.x + ',' + this.y + ')';}; var p = novo ponto (1, 2);Aqui, o ponto do construtor terá um objeto de protótipo (protótipo), que contém um ponteiro para apontar (construtor), e a instância P contém um ponteiro interno para o objeto protótipo (prop). Portanto, toda a herança é implementada através da cadeia de protótipo. Para detalhes, consulte este artigo do meu: protótipo e construtor em javascript
aula
O ES6 fornece um estilo de escrita mais próximo dos idiomas tradicionais, introduzindo o conceito de classe como modelo para objetos. Através da palavra -chave da classe, você pode definir uma classe. Mas as classes são apenas açúcar sintático para o padrão orientado a objetos baseado em protótipo. Existem críticas mistas sobre a introdução da classe, e muitas pessoas pensam que é uma falha importante, mas para mim, é um bom açúcar de sintaxe, porque a maneira usual de herdar as cadeias de protótipos geralmente pode me envolver por um tempo.
// define a classe de classe ponto {construtor (x, y) {this.x = x; this.y = y;} tostring () {return '(' + this.x + ',' + this.y + ')';}} var p = novo ponto (1, 2);• Existe um método construtor na classe, que é o método padrão da classe. Este método é chamado automaticamente ao gerar uma instância de objeto através do novo comando. Uma classe deve ter um método construtor. Se não estiver explicitamente definido, um método de construtor vazio será adicionado por padrão.
• A palavra -chave no método do construtor representa um objeto de instância.
• Ao definir o método de "classe" (como a tostragem no exemplo acima), você não precisa adicionar a função da palavra -chave antes dela, basta colocar a definição de função. Além disso, não há separação de vírgula entre os métodos, como um erro será relatado se adicionado.
• Ao usá -lo, você também usa o novo comando diretamente na classe, o que é exatamente o mesmo que o uso do construtor.
• Todos os métodos de uma classe são definidos na propriedade do protótipo da classe
Herança de classe - estender
A herança entre a classe pode ser alcançada através da palavra -chave Extends, que é muito mais clara e mais conveniente que a herança do ES5, modificando a cadeia de protótipo.
classe colorpoint estende o ponto {construtor (x, y, cor) {super (x, y); // Ligue para o construtor (x, y) da classe pai (x, y) this.color = color;} tostring () {return this.color + '' + super.toString (); // Ligue para o tostring () da classe pai}}• A super -palavra -chave, quando chamada de função (ou seja, super (... args)), representa o construtor da classe pai; Quando chamado como um objeto (ou seja, super.prop ou super.method ()), representa a classe pai. Aqui, ele representa o construtor da classe pai e é usado para criar esse objeto da classe pai.
• A subclasse deve chamar o método super no método do construtor; caso contrário, um erro será relatado ao criar uma nova instância. Isso ocorre porque a subclasse não possui seu próprio objeto, mas herda esse objeto da classe pai e o processa. Se o método super não for chamado, a subclasse não receberá esse objeto.
Modular
Historicamente, o JavaScript nunca teve um sistema de módulos e é impossível dividir um grande programa em pequenos arquivos interdependentes e depois montá -los de uma maneira simples, o que criou um enorme obstáculo ao desenvolvimento de projetos grandes e complexos. Para se adaptar ao desenvolvimento de grandes módulos, a comunidade formulou algumas soluções de carregamento de módulos, como CMD e AMD.
Escrita modular do ES6:
importar {stat, existe, readfile} de 'fs';A essência do código acima é carregar 3 métodos do módulo FS, e os outros métodos não são carregados. Esse tipo de carregamento é chamado de "carregamento em tempo de compilação", ou seja, o ES6 pode concluir o carregamento do módulo no tempo de compilação, o que é mais eficiente que o método de carregamento do módulo Commonjs. Obviamente, isso também leva à incapacidade de fazer referência ao próprio módulo ES6, porque não é um objeto.
A função do módulo é composta principalmente de dois comandos:
•exportar
A interface externa usada para especificar o módulo e a interface externa devem estabelecer uma relação de correspondência individual com as variáveis dentro do módulo.
// Método de gravação Um exportar var m = 1; // Exportação de erro 1; // Método de gravação dois var m = 1; exportar {m}; // Exportar erro m; // Método de gravação três nomes var n = 1; export {n como m};•importar
Usado para inserir as funções fornecidas por outros módulos. Ele aceita um objeto (representado em aparelhos) que especifica o nome da variável a ser importado de outros módulos (também pode ser carregado usando * no total)
Interpolação de string
No desenvolvimento de JavaScript, geralmente precisamos produzir modelos de saída como este:
função dizhello (nome) {return "hello, meu nome é"+nome+"eu sou"+getage (18);} função getage (idade) {return idade;} sayhello ("marca") // "Olá, meu nome é marca eu tenho 18"Precisamos usar + para concatenar strings e variáveis (ou expressões). Os exemplos são relativamente simples, por isso parecem inócuos, mas uma vez mais complicados, eles parecerão bastante pesados e inconvenientes, e esse uso também nos torna cansativos. Nesse sentido, o ES6 introduz strings de modelo, que podem inserir com facilidade e graciosamente os valores de JS em strings.
String de modelo
Para cordas de modelo, é:
• Pacote com backsticks ``;
• Use $ {} para produzir valores;
• O conteúdo em $ {} pode ser qualquer expressão de JavaScript; portanto, as chamadas de função e as operações aritméticas são legais;
• Se um valor não for uma string, ele será convertido em uma string;
• Mantenha todos os espaços, novas linhas e recuos e produzam para a string de resultado (strings de múltiplas linhas podem ser escritas)
• Use backsticks e aparelhos internamente para escapar e use barras de barriga/
Para o exemplo acima, a sequência de modelos está escrita da seguinte forma:
função dizhello (nome) {return `hello, meu nome é $ {name} eu sou $ {getage (18)}`;} função getage (idade) {idade de retorno;} sayhello ("marca") // "Olá, meu nome é Brandi Am 18"Modo rigoroso
Um dos objetivos do modo rigoroso é permitir uma depuração mais rápida de erros. A melhor maneira de ajudar os desenvolvedores A depuração é lançar erros quando ocorrerem certos padrões em vez de falhar silenciosamente ou mostrar comportamento estranho (geralmente ocorrendo no modo não rito). O código no modo rigoroso lançará mais mensagens de erro, o que pode ajudar os desenvolvedores a perceber rapidamente alguns problemas que devem ser resolvidos imediatamente. No ES5, o modo rigoroso é opcional, mas no ES6, muitos recursos exigem o uso do modo rigoroso, o que nos ajuda a escrever um JavaScript melhor.
O exposto acima é o problema "defeito" do ES6 JavaScript aprimorado que o editor apresentou a você. Espero que seja útil para você. Se você tiver alguma dúvida, deixe -me uma mensagem e o editor responderá a você a tempo. Muito obrigado pelo seu apoio ao site wulin.com!