Recentemente, estou relendo "JavaScript Advanced Programming 3" e sinto que devo escrever alguns blogs para gravar alguns dos conhecimentos que aprendi, caso contrário, vou esquecê -lo. O que eu quero resumir hoje é o ambiente e o escopo de execução JS.
Primeiro, vamos falar sobre o ambiente de execução
1. Ambiente de execução
O conceito no livro, o ambiente de execução define outros dados aos quais variáveis ou funções têm acesso e determina seus respectivos comportamentos. Cada ambiente de execução possui um objeto variável associado a ele. Todas as variáveis e funções definidas no ambiente são armazenadas neste objeto. Embora não possamos acessar esse objeto ao escrever código, o analisador o usará em segundo plano ao processar dados.
O ambiente de execução é um conceito, um mecanismo que define se uma variável ou função tem permissão para acessar outros dados
No JavaScript, o código JavaScript executável é dividido em três tipos:
1. Código global, ou seja, código global que não está em nenhuma função, como: um arquivo js, código JS incorporado em páginas HTML, etc.
2. Código de avaliação, isto é, código JS que é executado dinamicamente usando a função avaliação ().
3. Código da função, ou seja, o código JS do corpo da função nas funções definidas pelo usuário.
Pule o código de avaliação e fale apenas sobre o ambiente de execução global e o ambiente de execução da função.
1. Ambiente global:
O ambiente global é o ambiente de execução mais periférico. O ambiente de execução global é considerado um objeto de janela. Portanto, todas as variáveis e funções globais são criadas como propriedades e métodos de objetos de janela. Quando o código é carregado no navegador, o ambiente de execução global é criado (o ambiente de execução global é destruído apenas quando fechamos a página da web ou o navegador). Por exemplo, em uma página, crie um ambiente de execução global quando o código JS for carregado pela primeira vez.
É também por isso que os fechamentos têm uma desvantagem de vazamento de memória. Porque as funções externas nos fechamentos são tratadas como ambiente global. Portanto, não será destruído e será mantido na memória.
2. Ambiente de execução da função
Cada função possui seu próprio ambiente de execução. Quando a execução entra em uma função, o ambiente de execução da função será empurrado para o topo de uma pilha de ambiente de execução e obterá direitos de execução. Quando essa função é executada, seu ambiente de execução é excluído da parte superior da pilha e o direito de execução é devolvido ao ambiente de execução anterior. Este é o fluxo de execução no programa ECMAScript.
Também pode ser interpretado desta maneira: quando uma função JavaScript é chamada, a função entrará no ambiente de execução correspondente à função. Se outra função for chamada, um novo ambiente de execução será criado e o processo de execução está nesse ambiente durante a chamada de função. Quando a função chamada retorna, o processo de execução retorna ao ambiente de execução original. Portanto, a execução do código JavaScript forma uma pilha de ambiente de execução.
Quando uma função é chamada, o ambiente local da função é criado (depois que o código na função é executado, o ambiente é destruído e todas as variáveis e definições de função armazenadas nele também são destruídas).
2-1 Período de definição
Quando uma função é definida, um atributo [[escopo]] será criado. Este objeto corresponde a uma lista de objetos. Os objetos na lista só podem ser acessados internamente pelo JavaScript e não podem ser acessados por sintaxe.
(Escopo significa escopo.)
Definimos uma função global A e, em seguida, a função A cria um atributo A [[escopo]]. No momento, [[escopo]] contém apenas o objeto global [objeto global].
Se definirmos uma função B dentro de A, a função B também criará um atributo [[escopo]]. O atributo de [[escopo]] de B contém dois objetos, um é o objeto ativo do objeto ativo A do objeto ativo e o outro é o objeto global. O objeto ativo de A está na frente e o objeto global está na parte de trás.
Em resumo, a ordem da lista de objetos na propriedade [SCOPE] de uma função é o objeto de ativação da camada de função anterior e, em seguida, a camada superior, até o objeto global mais externo.
Aqui está o código de amostra: A tem apenas um escopo, B tem dois escopos
// Função externa Função A () {var algumVar; // Função interna da função b () {var algumvar; }}2-2 Período de execução
Quando uma função é executada, ela entra no ambiente de execução da função. Primeiro, ele cria seu próprio objeto ativo [objeto de ativação] (esse objeto contém a definição disso, argumentos, variáveis locais (incluindo parâmetros nomeados) e uma cadeia de escopo de um objeto variável. Em seguida, copie o escopo do ambiente de execução em [Scope Chain] em ordem e, finalmente, empurre o objeto ativo para a parte superior da [scoppeio]]. variáveis e objetos que têm permissão para acessar o ambiente de execução.
// O primeiro passo é criar o ambiente de execução global. Contexto de execução global e objetos de atividade global. // Define o [[escopo]] global, que contém apenas objetos de janela // verifica as variáveis de definição global e objetos de função: cor 【indefinida】, ChangeColor 【FD cria ChanGecolor [[escopo]], que contém apenas objetos de atividade global] que são adicionados à janela, as variáveis globais e os objetos globais são definidos como as propinas globais. // O programa foi definido para que o ChanGecolor () possa ser executado em qualquer lugar deste ambiente de execução. The color has also been defined, but its value is undefined// The second step is color assigning "blue"var color = "blue";// It does not require assignment, it refers to its own function changecolor() { // The fourth step enters the execution environment of changecolor// Copy the changecolor [[scope]] to the scope chain // Create active objects, scan to define variables and define functions, Outro colorido 【indefinido】 e swapcolors 【fd cria os swapcolors [[scope]] e adicionam os objetos ativos e objetos ativos globais】 aos objetos ativos e também adicionam argumentos e isso // os objetos ativos são executados em qualquer outro que o programa tenha sido definido para que o programa. Outrocolor foi definido, mas seu valor é indefinido // a quinta atribuição de outrocolor "Red" var outrocolor = "Red"; // It does not require assignment, it refers to its own function swapcolors() { // Step 7 Enter the execution environment of swapcolors and create its active object // Copy swapcolors' [[scope]] to scope chain // Scan to define variables and define function objects, add variables tempcolor【undefined】, arguments and this // Push the active object into scope chain top // Step 8: o valor da atribuição do tempo de tempcolor de outrocolor, outra corporação e cor serão encontradas ao longo da cadeia de escopo e continuarão a executar var the tempcolor = outrocolor; outrocolor = cor; cor = tempcolor; } // Etapa 6: Execute swapcolors e insira seu ambiente de execução swapcolors ();} // etapa 3: execute o changeColor e insira seu ambiente de execução changeColor ();2-3 Identificador de acesso:
Quando um identificador é encontrado durante a execução do código JS, ele pesquisará na cadeia de escopo do contexto de execução (contexto de execução) com base no nome do identificador. A partir do primeiro objeto da cadeia do escopo (o objeto de ativação da função), se não for encontrado, procure o próximo objeto na cadeia do escopo e repita até que a definição do identificador seja encontrada. Se o último objeto no escopo não for encontrado após a pesquisa da pesquisa, ou seja, o objeto global (objeto global), um erro será lançado, levando indefinido.
2 Cadeia de escopo/escopo (cadeia de escopo/escopo)
Quando o código é executado em um ambiente, uma cadeia de escopo é criada. O objetivo da cadeia de escopo é garantir o acesso ordenado a todas as variáveis e funções que têm permissão para acessar o ambiente de execução. Toda a cadeia de escopo é uma lista vinculada construída por objetos variáveis em diferentes locais de execução, de acordo com as regras. A extremidade frontal da cadeia de escopo é sempre o objeto variável no ambiente em que o código atualmente executado está localizado.
Se esse ambiente for uma função, seu objeto de ativação será usado como um objeto variável. O objeto ativo contém apenas uma variável no início, que é o objeto de argumentos dentro da função. O próximo objeto variável na cadeia de escopo vem do ambiente de inclusão da função, e o próximo objeto variável vem do próximo ambiente de inclusão. Dessa maneira, continua para o ambiente de execução global, e o objeto variável do ambiente de execução global é sempre o último objeto na cadeia de escopo.
Como mostrado na figura:
Exemplos no livro:
var color = "azul"; function chanGecolor () {var outrocolor = "vermelho"; função swapcolors () {var tempcolor = outrocolor; outrocolor = cor; cor = tempcolor; // TODO algo} swapColors ();} chanGecolor (); // tempcolor e anocolor não podem ser acessados aqui; Mas a cor pode ser acessada; alerta ("a cor agora é"+cor);Através da análise acima, podemos saber que o ambiente interno pode acessar todos os ambientes externos através de cadeias de escopo, mas o ambiente externo não pode acessar nenhuma variável e funções no ambiente interno.
Esses ambientes são lineares e ordenados. Cada ambiente pode procurar cadeias de escopo para cima para consultar variáveis e nomes de funções; No entanto, qualquer ambiente não pode entrar em outro ambiente de execução, procurando correntes de escopo para baixo.
Para a função swapcolor () no exemplo acima, sua cadeia de escopo inclui: objeto variável swapcolor (), objeto variável changeColor () e objeto global. O ambiente local do swapcolor () começa a procurar variáveis e nomes de funções em seu próprio objeto variável. Se não puder ser encontrado, procure a cadeia de escopo ChangeColor para cima. . . . . E assim por diante. No entanto, a função ChanGecolor () não pode acessar variáveis em Swapcolor
Apocalipse: tente usar variáveis locais para reduzir o tempo de pesquisa
1. Sem escopo no nível do bloco
Ao contrário de C, C ++ e Java, o JavaScript não possui escopo no nível do bloco. Veja o seguinte código:
if (true) {var myvar = "zhang san"; } alerta (myvar); // zhang sanSe houver um escopo em nível de bloco, o Myvar não poderá ser acessado de fora. Veja o seguinte
for (var i = 0; i <10; i ++) {console.log (i)} alert (i); // 10Para idiomas com escopo no nível do bloco, como Java ou Code C#, eu é uma variável inicializada e não posso ser acessada fora. Como eu só existo no peso do loop, depois de executar o loop for, todas as variáveis no for são destruídas. Este não é o caso em JavaScript. A declaração de variável para for será adicionada ao ambiente atual de execução (aqui está o ambiente de execução global). Portanto, após a conclusão do loop for, a variável ainda existe no ambiente de execução fora do loop. Portanto, 10 será emitido.
2. Declare variáveis
Quando uma variável é declarada usando VAR, essa variável será adicionada automaticamente ao ambiente disponível mais próximo. Para o interior de uma função, o ambiente mais próximo são as variáveis locais da função. Se a variável não for inicializada, a variável será adicionada automaticamente à função global.
O código é o seguinte:
var name = "xiao ming"; function getName () {alert (nome); // 'indefinido' var name = 'xiao huang'; alerta (nome); // xiao huang} getName ()Por que o primeiro nome é indefinido? Isso ocorre porque o analisador JavaScript entra em um ambiente de execução de função e digitaliza var e função primeiro.
É equivalente a promover a declaração VAR ou função [Declaração de Função] para o topo do ambiente de execução.
Em outras palavras, ao inserir nossa função GetName, o mecanismo de pesquisa de identificador encontra o VAR, e o nome é o nome da variável local, não o nome global, porque o nome na função é promovido ao topo.
O código acima será analisado da seguinte maneira:
var name = "xiao ming"; function getName () {var name; alerta (nome); // 'indefinido' var name = 'xiao huang'; alerta (nome); // xiao huang} getName ()Estender a corrente de escopo:
Embora existam apenas dois tipos de ambientes de execução - escopo global e escopo funcional, a cadeia de escopo ainda pode ser estendida de alguma forma. Porque algumas declarações podem adicionar um objeto variável temporário à parte superior da cadeia de escopo.
Existem duas situações em que isso acontece:
1. O bloco de captura da instrução Try-Catch;
2. Com declaração;
O acima é tudo sobre este artigo. Espero que seja útil que todos aprendam e entendam o ambiente e o escopo de execução de JavaScript.