Una de las características más importantes en JavaScript es el uso de cierres. Debido al uso de cierres, el alcance actual siempre puede acceder a alcances externos. Debido a que JavaScript no tiene un alcance de nivel de bloque y solo el alcance de la función, el uso de cierres está estrechamente relacionado con las funciones.
Simular variables privadas
La copia del código es la siguiente:
contador de funciones (inicio) {
Var count = inicio;
devolver {
increment: function () {
contar ++;
},
get: functer () {
recuento de retorno;
}
}
}
var foo = contador (4);
foo.increment ();
foo.get (); // 5
Aquí el contador devuelve dos cierres: incremento de funciones y obtenga. Estas dos funciones mantienen el acceso al alcance del contador, por lo que pueden acceder al recuento de variables definidas en el alcance del recuento.
Mecanismo de trabajo de variables privadas
Dado que JavaScript no puede asignar valores y referencias a los alcances, en el ejemplo anterior, no hay forma de acceder directamente al recuento de variables privadas internas desde el exterior. La única forma es acceder a él definiendo el cierre.
La copia del código es la siguiente:
var foo = nuevo contador (4);
foo.hack = function () {
recuento = 1337;
};
El código anterior no cambia el valor de la variable de recuento dentro del alcance del contador, porque el hack no se define dentro del contador. El código anterior solo creará o sobrescribirá el recuento de variables globales.
Cierres en el bucle
Uno de los errores más fáciles es usar cierres dentro de un bucle.
La copia del código es la siguiente:
para (var i = 0; i <10; i ++) {
setTimeOut (function () {
console.log (i);
}, 1000);
}
El código anterior no emitirá de 0 a 9, sino que saldrá 10 veces continuamente.
El anonimato anterior mantendrá una referencia a la variable i. Cuando se llama a la función console.log para iniciar la salida, este es el bucle que ha terminado, y la variable I ya es 10.
Para evitar el error anterior, necesitamos crear una copia de la variable que valoro cada vez que bucee.
Evite los errores de cotización
Para copiar el valor de una variable en el bucle, la mejor manera es agregar una función anónima a la capa externa y ejecutarlo de inmediato.
La copia del código es la siguiente:
para (var i = 0; i <10; i ++) {
(función (e) {
setTimeOut (function () {
console.log (e);
}, 1000);
})(i);
}
Esta función anónima externa toma la variable de bucle I como el primer parámetro y copia su valor a su propio parámetro e.
La función anónima externa pasa el parámetro E a SetTimeOut, por lo que SetTimeOut tiene una referencia al parámetro e. Además, el valor de este parámetro E no cambiará debido a los cambios de bucle externos.
Hay otra forma de lograr el mismo efecto, que es devolver una función anónima en la función anónima en SetTimeOut:
La copia del código es la siguiente:
para (var i = 0; i <10; i ++) {
setTimeOut ((function (e) {
Función de retorno () {
console.log (e);
}
}) (i), 1000)
}
Además, también se puede lograr a través del método de enlace.
La copia del código es la siguiente:
para (var i = 0; i <10; i ++) {
setTimeOut (console.log.bind (consola, i), 1000);
}
Al final del artículo, resumamos:
(1) El cierre es un principio de diseño. Simplifica las llamadas de los usuarios analizando el contexto, permitiendo al usuario lograr su propósito sin saberlo;
(2) Los artículos en línea convencionales sobre el análisis de los cierres son en realidad contrarios al principio de cierre. Si necesita conocer los detalles del cierre que se utilizará bien, este cierre es una falla de diseño;
(3) Trate de aprender lo menos posible.