Na introdução anterior, já sabemos que o JavaScript não tem função no nível do bloco, apenas escopo no nível da função.
A cópia do código é a seguinte:
function test () {// um escopo
para (var i = 0; i <10; i ++) {// não é um escopo
// contar
}
console.log (i); // 10
}
Também não há espaço para nome exibido no JavaScript, o que significa que tudo é definido no escopo global. Cada vez que uma variável é referenciada, o JavaScript atravessa todo o escopo global até que seja encontrado. Se a variável ainda não for encontrada através de todo o escopo global, um erro de reference Eerror será lançado.
Por favor, insira uma descrição da imagem
Variáveis globais implícitas
A cópia do código é a seguinte:
// script a
foo = '42';
// script b
var foo = '42'
Os dois exemplos acima têm efeitos diferentes. O primeiro definirá a variável Foo no escopo global, enquanto o segundo definirá a variável Foo no escopo atual.
Devemos observar que, se você não usar a palavra -chave VAR, ela terá um impacto inesperado.
A cópia do código é a seguinte:
// Escopo global
var foo = 42;
function test () {
// escopo local
foo = 21;
}
teste();
foo; // 21
Como o VAR não é usado para definir a variável Foo no teste de função, a variável global Foo fora da função será substituída. Embora não pareça um grande problema, se houver milhares de linhas de código, será um bug difícil de rastrear.
A cópia do código é a seguinte:
// Escopo global
var itens = [/ * alguma lista */];
for (var i = 0; i <10; i ++) {
subbloop ();
}
função subbloop () {
// Escopo de subbloop
para (i = 0; i <10; i ++) {// declaração vars ausente
// Faça coisas incríveis!
}
}
No exemplo acima, o loop externo será interrompido quando a primeira execução for executada, porque a variável I dentro da função subbloop substituirá a variável global externa i. Precisamos adicionar apenas um VAR dentro da função para evitar esse erro, por isso não devemos esquecer de adicionar a palavra -chave VAR ao definir variáveis. A menos que queira ter um impacto nas variáveis globais externas.
Variáveis locais
As variáveis locais no JavaScript só podem ser geradas de duas maneiras, uma é declarada através da palavra -chave VAR e a outra é usada como parâmetros formais da função.
A cópia do código é a seguinte:
// Escopo global
var foo = 1;
barra var = 2;
var i = 2;
teste de função (i) {
// Escopo local do teste de função
i = 5;
var foo = 3;
bar = 4;
}
teste (10);
Neste momento, as variáveis I e Foo dentro do teste de função são variáveis locais, e a barra substituirá a barra variável global externa.
Içar
O JavaScript promoverá declarações variáveis, o que significa que as expressões VAR e as declarações de função serão promovidas ao topo do escopo.
A cópia do código é a seguinte:
bar();
var bar = function () {};
var algum valor = 42;
teste();
Teste de função (dados) {
if (false) {
goo = 1;
} outro {
var goo = 2;
}
for (var i = 0; i <100; i ++) {
var e = dados [i];
}
}
Antes do execução do código acima, a declaração do teste de expressão e função do VAR será promovida ao topo, para que o programa seja executado normalmente e não relatará um erro.
A cópia do código é a seguinte:
// As declarações var foram movidas para cá
barra var, algum valor; // Padrão para 'indefinido'
// A declaração de função também foi movida
Teste de função (dados) {
var goo, i, e; // O escopo do bloco ausente os move aqui
if (false) {
goo = 1;
} outro {
goo = 2;
}
for (i = 0; i <100; i ++) {
e = dados [i];
}
}
bar(); // falha com um TypeError, já que o bar ainda é "indefinido"
algum valor = 42; // As atribuições não são afetadas pela iça
bar = function () {};
teste();
Como o JavaScript não possui escopo no nível do bloco, isso não apenas melhorará a expressão do VAR, mas também tornará a estrutura se menos intuitiva.
No exemplo acima, embora pareça que, se estiver operando na variável global Goo, de fato, como a gosma variável é promovida, a variável local é modificada.
Se você não entender as regras de elevação, poderá pensar que o código a seguir lançará um erro de referência.
A cópia do código é a seguinte:
// Verifique se alguma coisa foi inicializada
if (! Algumkentnthingthing) {
var alguma coisa importante = {};
}
Obviamente, o código acima não está errado, porque a expressão do VAR foi promovida ao topo antes da execução do código.
A cópia do código é a seguinte:
var algo importante;
// Outro código pode inicializar algo aqui, ou não
// Verifique se está lá
if (! Algumkentnthingthing) {
Algum importante é o que = {};
}
Aqui, eu gostaria de recomendar a postagem do blog do @nightire fã GE "Entendering JavaScript (II)", o que explica muito a melhoria.
Ordem de resolução de nome
Ao tentar acessar uma variável FOO em um escopo de função, o JavaScript procurará isso na seguinte ordem:
Se existe uma definição de var foo no escopo atual.
Se existe uma variável FOO no parâmetro da função.
Se a função em si é foo.
Salte para o domínio da definição externa e comece a olhar para cima da primeira parte.
Espaço para nome
Um dos problemas mais comuns é nomear conflitos, porque o JavaScript tem apenas um escopo global. Mas esse problema pode ser resolvido por funções externas anônimas.
A cópia do código é a seguinte:
(function () {
// um "espaço para nome" auto -contido
window.foo = function () {
// Um fechamento exposto
};
}) (); // execute a função imediatamente
As funções anônimas no exemplo acima são consideradas expressões, portanto são executadas.
A cópia do código é a seguinte:
(// avaliar a função dentro dos pais
function () {}
) // e retorne o objeto de função
() // Chame o resultado da avaliação
Obviamente, também podemos usar outros métodos para chamar expressões de função, estruturas diferentes, mas o mesmo efeito.
A cópia do código é a seguinte:
// alguns outros estilos para invocar diretamente o
!função(){}()
+function () {} ()
(função(){}());
// e assim por diante ...
Resumir
Recomenda -se que você use funções externas anônimas para encapsular o código no espaço, que não apenas resolve conflitos de namespace, mas também facilita a modularização do programa.
Além disso, o uso de variáveis globais não é um bom hábito, o que trará altos custos de manutenção e é propenso a erros.
Os espaços para nome têm os mesmos tipos, funções, variáveis, modelos, etc., todos pertencem a entidades.
A principal semelhança de uma entidade é que ela pode ter um nome. (Além disso, uma tag também pode ter um nome, mas não é uma entidade.)
O escopo do espaço para nome é um termo geral no escopo, paralelo ao escopo do bloqueio, escopo de classe, escopo do protótipo de função e escopo da função (válido apenas para rótulos). Os nomes declarados dentro do espaço para nome estão no escopo do espaço para nome. Os nomes globais são considerados no espaço de nome de nome global implícito.
A função de um espaço para nome é realmente o escopo, mas é diferente de um escopo simples. Você pode declarar o mesmo espaço para nome em vários lugares em várias vezes, mas o conteúdo interno não pode ser redefinido. Eles acabarão sintetizando um espaço para nome, assim como as definições de macro STD, em todos os lugares.