Prefácio: ainda é um artigo introdutório. Existem vários recursos de linguagem muito importantes no JavaScript - objetos, herança de protótipo e fechamentos. Entre eles, os fechamentos estão um novo recurso de idioma para programadores que usam a linguagem estática tradicional C/C ++. Este artigo começará com exemplos para introduzir os recursos do idioma dos fechamentos de JavaScript e combinar algumas especificações do idioma do ECMAScript para permitir que os leitores entendam mais profundamente os fechamentos.
Nota: Este artigo é um artigo introdutório e os materiais de exemplo são compilados na Internet. Se você é um mestre, pode apresentar sugestões e opiniões técnicas sobre o artigo. Este artigo discute o JavaScript e você não deseja comparar idiomas. Se você está naturalmente desconfortável com o JavaScript, faça um desvio.
O que é um fechamento
O que é um fechamento? O fechamento é o fechamento, que é um novo recurso que os idiomas estáticos não possuem. Mas os fechamentos não são algo tão complicado que são incompreensíveis. Em resumo, os fechamentos são:
Os fechamentos são o conjunto de variáveis locais da função, mas essas variáveis locais continuarão a existir após o retorno da função.
Os fechamentos são a "pilha" da função e não são liberados após o retorno da função. Também podemos entender que essas pilhas de função não são alocadas na pilha, mas são alocadas na pilha.
Ao definir outra função dentro de uma função, um fechamento será gerado
A segunda definição acima é a primeira descrição suplementar, que extrai o objeto predicato do sujeito da primeira definição - o fechamento é um conjunto de funções 'variável local'. É que essa variável local pode ser acessada após o retorno da função. (Esta não é uma definição oficial, mas essa definição deve ser mais propícia à sua compreensão dos fechamentos)
Como variáveis locais, elas podem ser acessadas pelo código na função e não há diferença entre isso e a linguagem estática. A diferença entre os fechamentos é que as variáveis locais ainda podem ser acessadas por código fora da função após a execução da função. Isso significa que a função deve retornar uma "referência" ao fechamento ou atribuir essa "referência" a uma variável externa para garantir que as variáveis locais no fechamento sejam acessadas por código externo. Obviamente, a entidade que contém essa referência deve ser um objeto, porque no JavaScript, todo o restante, exceto que os tipos básicos são objetos. Infelizmente, o ECMAScript não fornece membros e métodos relevantes para acessar variáveis locais no fechamento. No entanto, no ECMAScript, a função interna definida no objeto de função é uma variável local que pode acessar diretamente as funções externas. Através desse mecanismo, podemos concluir o acesso ao fechamento da seguinte maneira.
A cópia do código é a seguinte:
Função Saudação (Nome) {
var texto = 'hello' + nome; // variável local
// Cada vez que um fechamento é gerado e o objeto de função interno é retornado ao chamador
retornar function () {alert (text); }
}
var dizhello = saudação ("fechamento");
dizhello () // Acesse o texto variável local através do fechamento
O resultado da execução do código acima é: Hello Feching, porque após a função de saudação ser executada, a função SayHello () ainda pode acessar o texto da variável local definido nela.
Ok, este é o efeito do fechamento lendário. Os fechamentos têm muitos cenários e modos de aplicação em JavaScript, como Singleton, Power Constructor e outros modos JavaScript que são inseparáveis com o uso de fechamentos.
Modelo de fechamento do ecmascript
Como o ECMAScript implementa o fechamento? Se você deseja ter um entendimento profundo, pode obter as especificações do ECMAScript para pesquisa. Eu só darei uma explicação simples aqui, e o conteúdo também vem da Internet.
Quando a função do script ECMAScript é executada, cada associação de funções possui um cenário de contexto de execução (contexto de execução), que contém três partes.
O ambiente lexicalenvo
O ambiente variável
Esta ligação
O terceiro ponto dessa ligação não tem nada a ver com fechamentos e não é discutido neste artigo. Um identificador variável usado no ambiente gramatical para analisar o processo de execução da função. Podemos pensar em um ambiente gramatical como um objeto que contém dois componentes importantes, o registro do ambiente (reviroment Recode) e uma referência externa (ponteiro). O registro do ambiente contém variáveis locais e variáveis de parâmetros declarados internamente pela função, e os pontos de referência externos para o cenário de execução de contexto do objeto de função externa. Esse valor de referência é nulo no cenário de contexto global. Essa estrutura de dados forma uma lista vinculada unidirecional, cada referência aponta para o cenário de contexto externo.
Por exemplo, o modelo de fechamento em nosso exemplo acima deve ser assim. A função Sayhello está no nível mais baixo, o nível superior é a saudação da função e o nível mais externo é o cenário global. Conforme mostrado na figura abaixo: portanto, quando diz que o Sayhello é chamado, diz que o Hello encontrará o valor do texto variável local através da cena do contexto, de modo que o ambiente variável "Hello Feching" (o ambiente variável) e o ambiente gramatical são basicamente os mesmos. Para diferenças específicas, consulte o documento de especificação do ECMAScript.
Amostra coluna de fechamento
No artigo anterior, entendo aproximadamente o que é o fechamento de JavaScript e como os fechamentos são implementados no JavaScript. Abaixo, ajudaremos você a entender mais profundamente os fechamentos, visando alguns exemplos. Existem 5 exemplos abaixo, e os exemplos são do fechamento de JavaScript para manequins (espelho). Exemplo 1: as variáveis locais nos fechamentos são referências em vez de cópias
A cópia do código é a seguinte:
função diz667 () {
// variável local que acaba dentro do fechamento
var num = 666;
var sayArt = function () {alert (num); }
num ++;
retornar dizeLert;
}
var sayArt = SAY667 ();
Sayalert ()
Portanto, o resultado da execução deve aparecer 667 em vez de 666.
Exemplo 2: Várias funções ligam o mesmo fechamento porque são definidas na mesma função.
A cópia do código é a seguinte:
Função setupsomeGlobals () {
// variável local que acaba dentro do fechamento
var num = 666;
// armazena algumas referências a funções como variáveis globais
galertNumber = function () {alert (num); }
GINCREASENBUME = function () {num ++; }
gSetNumber = function (x) {num = x; }
}
setupsomeGlobals (); // atribui valores a três variáveis globais
galertNumber (); // 666
GINCREASENBORME ();
galertNumber (); // 667
gSetNumber (12); //
galertNumber (); // 12
Exemplo 3: Ao atribuir funções em um loop, essas funções ligarão o mesmo fechamento
A cópia do código é a seguinte:
Função BuildList (List) {
var resultado = [];
for (var i = 0; i <list.length; i ++) {
var item = 'item' + list [i];
resultado.push (function () {alert (item + '' + list [i])});
}
resultado de retorno;
}
função testlist () {
var fnList = Buildlist ([1,2,3]);
// usando J apenas para ajudar a evitar a confusão - poderia usar eu
for (var j = 0; j <fnlist.length; j ++) {
fnlist [j] ();
}
}
O resultado da execução da lista de testes é que a janela indefinida do item3 aparece três vezes, porque essas três funções ligam o mesmo fechamento, e o valor do item é o último resultado calculado, mas quando eu pulo do loop, o valor I é 4, portanto o resultado da lista [4] é indefinido.
Exemplo 4: Todas as variáveis locais de funções externas estão no fechamento, mesmo que essa variável seja declarada após a definição de função interna.
A cópia do código é a seguinte:
function sayalice () {
var sayArt = function () {alert (Alice); }
// variável local que acaba dentro do fechamento
var alice = 'Olá Alice';
retornar dizeLert;
}
var helloalice = sayalice ();
HelloAlice ();
O resultado da execução é uma janela com pop-up "Hello Alice". Mesmo que a variável local declara após a função dizer, a variável local ainda pode ser acessada.
Exemplo 5: Crie um novo fechamento toda vez que a função é chamada
A cópia do código é a seguinte:
função newclosure (somenum, someref) {
// variáveis locais que acabam dentro do fechamento
var num = somenum;
var anarray = [1,2,3];
var ref = Someref;
Função de retorno (x) {
num += x;
anarray.push (num);
alerta ('num:' + num +
'/nanarray' + anarray.toString () +
'/nref.womevar' + ref.omevar);
}
}
fechamento1 = newclosure (40, {algumvar: 'fechamento 1'});
fechamento2 = newclosure (1000, {algumvar: 'fechamento 2'});
fechamento1 (5); // num: 45 ANARRAY [1,2,3,45] Ref: 'SomeVar Closure1'
Closure2 (-10); // num: 990 anarray [1,2,3,990] Ref: 'Somevar Closure2'
Aplicação de fechamentos
Singleton Single Piece:
A cópia do código é a seguinte:
var singleton = function () {
var privateVariable;
função privatefunção (x) {
... PrivateVariable ...
}
retornar {
FirstMethod: function (a, b) {
... PrivateVariable ...
},
SecondMethod: function (c) {
... privatefunction () ...
}
};
} ();
Esta única peça é alcançada através de um fechamento. O encapsulamento de membros e métodos privados é concluído por meio de fechamentos. A função principal anônima retorna um objeto. O objeto contém dois métodos, o método 1 pode usar variáveis privadas e o método 2 pode acessar funções privadas internas. A coisa a ser observada é o '()' 'onde a função principal anônima termina. Sem isso '()', uma única peça não pode ser produzida. Porque as funções anônimas só podem retornar objetos exclusivos e não podem ser chamados em outro lugar. Este é o método de usar fechamentos para gerar peças únicas.