Los cierres JS solo se pueden comer hasta por mil capas de mango

Al aprender js, aprenderás más o menos sobre los cierres, porque es un poco extraño, por lo que es oscuro. Aquí hay algunos conceptos de creación de cierre.

 Los cierres pueden crear un entorno independiente. El entorno en cada cierre es independiente y no interfiere entre sí. Se producirá una pérdida de memoria en el cierre. Cada vez que se ejecuta la función externa, la dirección de referencia de la función externa es diferente y se recrea una nueva dirección .

( Artículo fuente arriba: https : //blog.csdn.net/weixin_43586120/article/details/89456183 , muy buen artículo, le recomiendo que eche un vistazo. Algunos de los ejemplos de código a continuación también se refieren a este artículo, si El autor es ofensivo, eliminaré este artículo )

       Luego, si leemos cuidadosamente este párrafo (10 veces en silencio, reduzca la velocidad de las palabras en rojo), encontrará que se creará una nueva dirección cuando la dirección referenciada externamente sea diferente. Las variables que contiene no se actualizarán. Cuando se haga referencia a la nueva dirección , se actualizarán las variables del cierre . En base a este pasaje llegamos a "Kang Kang", algunos ejemplos que entenderemos.

Ejemplo 1

function fun1(){
    var num = 0;
    function fun2(){
      num ++;
      console.log(num)
    }
    return fun2
}
var a = fun1();
var b = fun1();
a();
b();
a();
b(); 
//输出为 1 1 2 2

Mire la almeja, usando la oración anterior para entender, ¿es una dirección nueva? Si ¿Es b una nueva dirección? Si Por lo tanto, ayb no se afectan entre sí. Entonces, ¿cuántos a () se invocan antes de que b () no afecten a la propia variable de b? ¿Cuál, lo llamo de la siguiente manera?

fun1()()
fun1()()
//输出为 1 1 

Lo mismo, las dos direcciones referenciadas son diferentes, por lo que no se afectan entre sí. (Además, algunos lectores pueden no entender por qué hay dos paréntesis. Esto se debe a que el primer paréntesis es llamar al método fun1 , y luego fun1 devuelve el método fun2 , por lo que el significado del segundo paréntesis es llamar al método fun2 en fun1 ). Este suplemento presentamos el siguiente ejemplo.

Ejemplo 2

var fun1 = function(x) { 
    var sum = 1; 
    var fun2 = function(x) { 
        sum = sum + x; 
        return fun2;    
    } 
    fun2.toString = function() { 
        return sum; 
    }
    return fun2; 
} 
console.log(fun1(1)(2)(3));  
//输出为 6 

Algunos lectores pueden estar avergonzados cuando aparecen. Que es esto Pero somos personas capacitadas profesionalmente y no tendremos miedo a menos que sea realmente aterrador. Pero esto no es difícil de entender, la interpretación de los tres corchetes puede referirse a un párrafo para agregar. Eche un vistazo más de cerca a estos códigos. El primer paréntesis, fun1 (1), generará una nueva dirección después de que se ejecute el método, ejecute sum = 1 y devuelva la función fun2. El segundo paréntesis es llamar a la función fun2 devuelta. La función fun2 puede recibir un parámetro y agregarlo a la suma. Debido a que la memoria no ha cambiado, en este momento, la suma es el 1 ejecutado por el primer paréntesis, no el 1 entrante, por lo que ejecuta el siguiente código:

console.log(fun1()(2)(3));  
//输出为 6 
console.log(fun1(800000)(2)(3));  
//输出为 6 

Es lo mismo Algunos estudiantes también pueden preguntarse: "¿Qué parámetro x?" En realidad, esta x, porque fun2 no se llama en fun1, pero se llama al método toString de fun2, por lo que estas dos x no tienen efecto a menos que se llame fun1 Fun2. Después de la ejecución de fun2 (2) anterior, el valor de la suma se convierte en 1 + 2, que es 3, lo mismo, el tercer par se convierte en 3 + 3, por lo que el resultado es 6, por supuesto, siempre puede establecer Bebé sigue. Mirando hacia atrás en todo el proceso, la dirección donde se creó el cierre no ha cambiado, por lo que el valor de la suma no se ha actualizado. En base a esto, hagamos una revisión y llamemos a fun1 en fun2, vea el ejemplo 3 a continuación.

Ejemplo 3

function fun1(num1, num2) {
      console.log(num2);
      return {
           fun2:function(num3) {
                 return fun1(num3, num1);
           }
      };
}
var a = fun1(0);  //undefined
a.fun2(1);        //0  
a.fun2(2);        //0  
a.fun2(3);        //0  
var b = fun1(0).fun2(1).fun2(2).fun2(3);
//undefined  0  1  2

Tal vez pareces estupefacto de nuevo, ¿por qué es una matrioska otra vez? De hecho, Ollie Giao está terminado (el otro código es el mismo nombre de fun2 y fun1, eso es asqueroso, así que separé específicamente los dos nombres aquí para una fácil comprensión. De hecho, el mismo nombre es el mismo).

Mire aquí, a es una nueva dirección, b también es una nueva dirección, estos dos no se afectan entre sí. No importa cómo opera a, no puede afectar b. Después de confirmar esto, echemos un vistazo al código nuevamente. Según la interpretación del párrafo anterior, todos los que han leído lo anterior ya entienden siete u ocho. Por qué el primero no está definido, porque no se pasan parámetros, por qué a.fun2 (1) ... etc. son todos 0, puede entender la ejecución de fun2, num1 = 0, ya en var a = fun1 (0); Se ha determinado que no importa cómo a2 llame a fun2 más tarde, no afectará a num1 = 1 de fun1. Y a.fun2 (x) luego mira el conjunto de muñecas en b. Lo mismo, es fácil de entender cuando lo traen; 

 

Finalmente, para resumir, para ver si las variables del cierre han cambiado, personalmente creo que depende de si la dirección del cierre ha cambiado. Indique si hay errores, muchas gracias.

3 artículos originales publicados · Me gusta5 · Visitantes1072

Supongo que te gusta

Origin blog.csdn.net/weixin_39394140/article/details/105551971
Recomendado
Clasificación