En la introducción anterior, ya sabemos que JavaScript no tiene función de nivel de bloque, solo alcance a nivel de función.
La copia del código es la siguiente:
función test () {// un alcance
para (var i = 0; i <10; i ++) {// no es un alcance
// contar
}
console.log (i); // 10
}
Tampoco se muestra el espacio de nombres en JavaScript, lo que significa que todo se define en el alcance global. Cada vez que se hace referencia a una variable, JavaScript atravesará todo el alcance global hasta que se encuentre. Si la variable aún no se encuentra a través del alcance global completo, se lanza un error de referenceerRor.
Ingrese una descripción de una imagen
Variables globales implícitas
La copia del código es la siguiente:
// Script a
foo = '42';
// script b
var foo = '42'
Los dos ejemplos anteriores tienen diferentes efectos. El primero definirá la variable FOO en el alcance global, mientras que el segundo definirá la variable FOO en el alcance actual.
Debemos tener en cuenta que si no usa la palabra clave var, tendrá un impacto inesperado.
La copia del código es la siguiente:
// alcance global
var foo = 42;
función test () {
// alcance local
foo = 21;
}
prueba();
foo; // 21
Dado que VAR no se usa para definir la variable FOO en la prueba de función, la variable global Foo fuera de la función se sobrescribirá. Aunque no parece un gran problema, si hay miles de líneas de código, será un error difícil de rastrear.
La copia del código es la siguiente:
// alcance global
VAR items = [/ * Some List */];
para (var i = 0; i <10; i ++) {
subloop ();
}
function subloop () {
// Alcance de subloop
para (i = 0; i <10; i ++) {// Declaración var faltando
// ¡Haz cosas increíbles!
}
}
En el ejemplo anterior, el bucle externo se detendrá cuando se ejecute la primera ejecución, porque la variable I dentro de la función SuBloop anulará la variable global externa i. Solo necesitamos agregar un VAR dentro de la función para evitar este error, por lo que no debemos olvidar agregar el VAR de palabras clave al definir variables. A menos que queramos tener un impacto en las variables globales externas.
Variables locales
Las variables locales en JavaScript solo se pueden generar de dos maneras, una se declara a través de la palabra clave var y la otra se usa como parámetros formales de la función.
La copia del código es la siguiente:
// alcance global
var foo = 1;
barra var = 2;
var i = 2;
prueba de función (i) {
// Alcance local de la prueba de función
i = 5;
var foo = 3;
barra = 4;
}
prueba (10);
En este momento, las variables I y Foo dentro de la prueba de función son variables locales, y la barra anulará la barra de variable global externa.
Polipasán
JavaScript promoverá declaraciones variables, lo que significa que tanto las expresiones VAR como las declaraciones de función se promoverán a la parte superior del alcance.
La copia del código es la siguiente:
bar();
var bar = function () {};
var someValue = 42;
prueba();
prueba de función (datos) {
if (false) {
Goo = 1;
} demás {
var goo = 2;
}
para (var i = 0; i <100; i ++) {
var e = data [i];
}
}
Antes de que se ejecute el código anterior, la declaración de expresión de VAR y prueba de función se promovirá a la parte superior, por lo que el programa se ejecutará normalmente y no informará un error.
La copia del código es la siguiente:
// Las declaraciones var se movieron aquí
bar bar, algún valor; // predeterminado a 'indefinido'
// La declaración de función también se subió
prueba de función (datos) {
Var Goo, I, E; // El alcance del bloque que falta los mueve aquí
if (false) {
Goo = 1;
} demás {
Goo = 2;
}
para (i = 0; i <100; i ++) {
e = datos [i];
}
}
bar(); // falla con un TypeError ya que la barra todavía está 'indefinida'
algún valor = 42; // Las tareas no se ven afectadas por el elevación
bar = function () {};
prueba();
Dado que JavaScript no tiene un alcance de nivel de bloque, esto no solo mejorará la expresión de VAR, sino que también hará que la estructura IF sea menos intuitiva.
En el ejemplo anterior, aunque parece que si funciona en el GOO de la variable global, de hecho, ya que se promueve la variable GOO, la variable local se modifica.
Si no tiene ninguna comprensión de las reglas de elevación, puede pensar que el siguiente código lanzará un error de referencia.
La copia del código es la siguiente:
// Verifique si se ha inicializado algo importante
if (! algo importante) {
var algo implacable = {};
}
Por supuesto, el código anterior no es incorrecto, porque la expresión VAR se ha promovido a la parte superior antes de que se ejecute el código.
La copia del código es la siguiente:
var de alguna importancia;
// otro código podría inicializar algo importante aquí, o no
// Asegúrate de que esté ahí
if (! algo importante) {
Algo importante = {};
}
Aquí me gustaría recomendar la publicación del blog de @Nightire Fan Ge "Comprender JavaScript (ii)", que explica la mejora muy a fondo.
Orden de resolución de nombre
Al intentar acceder a una variable FOO dentro de un alcance de funciones, JavaScript lo buscará en el siguiente orden:
Si hay una definición de var foo en el alcance actual.
Si hay una variable FOO en el parámetro de función.
Si la función en sí es foo.
Salta al dominio de definición externa y comienza a mirar hacia arriba desde la primera parte.
Espacio de nombres
Uno de los problemas más comunes es nombrar conflictos, porque JavaScript solo tiene un alcance global. Pero este problema puede resolverse mediante funciones externas anónimas.
La copia del código es la siguiente:
(función() {
// un "espacio de nombres" autónomo
window.foo = function () {
// un cierre expuesto
};
}) (); // ejecutar la función inmediatamente
Las funciones anónimas en el ejemplo anterior se consideran expresiones, por lo que se ejecutan.
La copia del código es la siguiente:
(// Evaluar la función dentro de los padres
función() {}
) // y devuelve el objeto de función
() // llame al resultado de la evaluación
Por supuesto, también podemos usar otros métodos para llamar a expresiones de funciones, diferentes estructuras, pero el mismo efecto.
La copia del código es la siguiente:
// algunos otros estilos para invocar directamente el
!función(){}()
+function () {} ()
(función(){}());
// etcétera...
Resumir
Se recomienda que use funciones externas anónimas para encapsular el código en el espacio, lo que no solo resuelve conflictos en el espacio de nombres, sino que también facilita la modularización del programa.
Además, el uso de variables globales no es un buen hábito, lo que traerá altos costos de mantenimiento y es propenso a los errores.
Los espacios de nombres tienen los mismos tipos, funciones, variables, plantillas, etc., todos pertenecen a entidades.
La principal comunidad de una entidad es que puede tener un nombre. (Además, una etiqueta también puede tener un nombre, pero no es una entidad).
El alcance del espacio de nombres es un término general en alcance, que es paralelo al alcance de la clase, el alcance de la clase, el alcance del prototipo de función y el alcance de la función (solo válido para etiquetas). Los nombres declarados dentro del espacio de nombres están en el alcance del espacio de nombres. Los nombres globales se consideran en el alcance implícito del espacio de nombres global.
La función de un espacio de nombres es de hecho un alcance, pero es diferente de un alcance simple. Puede declarar el mismo espacio de nombres en varios lugares en varias veces, pero el contenido interior no se puede redefinir. Eventualmente sintetizarán un espacio de nombres, al igual que STD, definiciones macro en todas partes.