1. ¿Qué es un cierre?
Un cierre es una función que tiene permiso para acceder a las variables en otro alcance de la función.
En pocas palabras, JavaScript permite el uso de funciones internas, es decir, las definiciones de funciones y las expresiones de funciones se encuentran en el cuerpo de funciones de otra función. Además, estas funciones internas pueden acceder a todas las variables locales, parámetros y otras funciones internas declaradas en la función externa donde residen. Cuando una de estas funciones internas se llama fuera de la función externa que las contiene, se forma un cierre.
2. El alcance de las variables
Para comprender los cierres, primero debe comprender el alcance de las variables.
Solo hay dos tipos de ámbitos de variables: variables globales y variables locales.
La característica especial del lenguaje JavaScript es que las variables globales se pueden leer directamente dentro de las funciones.
Se puede acceder a las variables de las funciones externas en la función interna porque la cadena de alcance de la función interna contiene el alcance de la función externa;
También se puede entender como: el rango de acción de la función interna se irradia al rango de acción de la función externa;
var n = 999; función f1 () {alerta (n);} f1 (); // 999Por otro lado, las variables locales dentro de la función, naturalmente, no se leen fuera de la función.
función f1 () {var n = 999;} alerta (n); // errorHay un lugar para tener en cuenta aquí. Al declarar las variables internamente, debe usar el comando VAR. Si no, ¡en realidad declara una variable global!
función f1 () {n = 999;} f1 (); alerta (n); // 9993. Varias formas de escribir y usar cierres
3.1. Agregue algunas propiedades a la función
círculo de funciones (r) {this.r = r; } Circle.pi = 3.14159; Circle.prototype.area = function () {return circle.pi * this.r * this.r; } var c = new Circle (1.0); alerta (c.area ()); //3.141593.2. Declare una variable y asigne una función a la variable como un valor.
var circle = function () {var obj = new Object (); obj.pi = 3.14159; obj.area = function (r) {return this.pi * r * r; } return obj; } var c = new Circle (); alerta (c.area (1.0)); //3.141593.3. Este método se usa con más frecuencia y es el más conveniente. var obj = {} es declarar un objeto vacío
var circle = {"pi": 3.14159, "área": function (r) {return this.pi * r * r; }}; alerta (circle.area (1.0)); // 3.141594. La función principal del cierre
Los cierres se pueden usar en muchos lugares. Tiene dos mayores usos: uno es que las variables dentro de la función se pueden leer como se mencionó anteriormente, y la otra es que los valores de estas variables siempre se mantienen en la memoria.
4.1. ¿Cómo leer las variables locales desde el exterior?
Por varias razones, a veces necesitamos obtener variables locales dentro de la función. Sin embargo, como se mencionó anteriormente, en circunstancias normales, esto no se puede hacer y solo se puede lograr a través de soluciones.
Eso es definir otra función dentro de la función.
función f1 () {var n = 999; función f2 () {alerta (n); // 999}}En el código anterior, la función F2 se incluye dentro de la función F1, y todas las variables locales dentro de F1 son visibles para F2. Pero al revés no es posible. Las variables locales dentro de F2 son invisibles para F1. Esta es la estructura de "alcance de la cadena" exclusiva del lenguaje JavaScript. Los objetos secundarios buscarán el nivel hacia arriba por nivel para todas las variables de los objetos principales. Por lo tanto, todas las variables del objeto principal son visibles para el objeto infantil, de lo contrario no es cierto.
Dado que F2 puede leer las variables locales en F1, siempre que se use F2 como valor de retorno, ¿no podemos leer sus variables internas fuera de F1?
función f1 () {var n = 999; función f2 () {alerta (n); } return f2;} var result = f1 (); resultado (); // 9994.2. ¿Cómo guardar siempre el valor de una variable en la memoria?
función f1 () {var n = 999; nadd = function () {n+= 1} function f2 () {alert (n); } return f2;} var result = f1 (); resultado (); // 999NADD (); resultado (); // 1000En este código, el resultado es en realidad la función de cierre F2. Se ejecuta dos veces en total, el primer valor es 999 y el segundo valor es 1000. Esto demuestra que la variable local N en la función F1 se ha mantenido en la memoria y no se borra automáticamente después de que se llama a F1.
¿Por qué está sucediendo esto? La razón es que F1 es la función principal de F2, y F2 se asigna a una variable global, que hace que F2 esté siempre en la memoria, y la existencia de F2 depende de F1. Por lo tanto, F1 siempre está en la memoria y no será reciclado por el mecanismo de recolección de basura después de que termine la llamada.
Otro punto notable en este código es que la línea "nadd = function () {n+= 1}" se usa primero antes de NADD, por lo que NADD es una variable global, no una variable local. En segundo lugar, el valor de NADD es una función anónima, y esta función anónima en sí misma también es un cierre, por lo que NADD es equivalente a un setter, que puede operar en variables locales dentro de la función fuera de la función.
5. Cierres y este objeto
Usar este objeto en cierres puede causar algunos problemas. Debido a que la ejecución de funciones anónimas es global, este objeto generalmente apunta a la ventana. El código es el siguiente:
var name = "The Window"; var objeto = {nombre: "mi objeto", getNameFun: function () {return function () {return this.name;};}}; alert (object.getNameFun () {}); // "The Window" (en modo no rictamente)Guarde este objeto en el alcance externo en una variable a la que se puede acceder mediante un cierre, y el cierre puede acceder al objeto. El código es el siguiente:
var name = "The Window"; var objeto = {nombre: "mi objeto", getNameFun: function () {var that = this; return function () {return that.name;};}}; alert (object.getNameFun () {}); // "Mi objeto"6. Cierres y filtraciones de memoria
Específicamente, si se almacena un elemento HTML en el alcance del cierre, significa que el elemento no puede ser destruido. como sigue:
function asignHandler () {var elemento = document.getElementById ("someElement"); element.OnClick = function () {alert (element.id);}}El código anterior crea un cierre como controlador de eventos de elementos del elemento, y este cierre crea una referencia circular. Dado que las funciones anónimas guardan una referencia al objeto activo de AsignHandler (), no será posible reducir el número de referencias al elemento. Mientras exista una función anónima, el número de referencias al elemento es al menos 1, por lo que la memoria que ocupa no se reciclará.
Resolver problemas de reciclaje interno reescribiendo el código:
función asignHandler () {var elemento = document.getElementById ("someElement"); var id = element.id; element.onclick = function () {alert (id);} element = null;}En el código anterior, el cierre de implementación no se refiere directamente al elemento, y aún se guardará una referencia en el objeto activo que contiene la función. Por lo tanto, es necesario establecer la variable de elemento en NULL, de modo que la memoria que ocupa se pueda reciclar normalmente.
7. Notas sobre el uso de cierres
1) Dado que los cierres causarán que todas las variables en la función se almacenen en la memoria, y el consumo de memoria es muy grande, los cierres no se pueden abusar, de lo contrario causará problemas de rendimiento de la página web y puede conducir a la fuga de memoria en IE. La solución es eliminar todas las variables locales que no se usan antes de salir de la función.
2) El cierre cambiará el valor de la variable dentro de la función principal fuera de la función principal. Por lo tanto, si usa la función principal como objeto, use el cierre como método público y use la variable interna como propiedad privada, tenga cuidado de no cambiar el valor de la variable interna de la función principal a voluntad.
Lo anterior es una explicación detallada de la escritura y la función de los cierres en JavaScript presentados por el editor. Espero que te sea útil. Si tiene alguna pregunta, déjame un mensaje y el editor le responderá a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!