Sobre la comprensión de los cierres en JavaScript

Prefacio

Los cierres son un punto de conocimiento muy importante en el desarrollo de front-end, y definitivamente se preguntarán en la entrevista.


Uno, la definición de cierre

Las referencias a la función y su estado circundante (entorno léxico, entorno léxico) se agrupan para formar un cierre (cierre). En otras palabras, el cierre le permite acceder al alcance de la función externa desde la función interna. En JavaScript, siempre que se crea una función, se genera un cierre cuando se genera la función.

En pocas palabras, un cierre es una función definida en una función .

P.ej:

function Clos(){
    
    
	var age = 32;
    function getNum(){
    
    
    	console.log(age);//32
        return age;
    }
    return getNum;
}
var get_A = Clos();//get_A将会得到Clos()最后的运行返回的结果.即getNum()函数体
get_A();//拿到了变量age的值:32
console.log(age);//报错:ReferenceError: age is not defined

El código anterior getNum()函数es un cierre , que se define en el cuerpo de la función denominada Clos ().


En segundo lugar, el papel del cierre

Las variables definidas dentro de una función pertenecen a variables locales. El ciclo de vida de una variable local es: cuando se llama a la función en la que se encuentra, se inicia. Una vez ejecutada la llamada, la variable local se liberará. Cuando necesitemos la variable interna de la función, Ha sido puesto en libertad y ya no se puede leer ¿Cómo solucionar este problema en este momento? Tenemos que encontrar una forma de extender su ciclo de vida.

También se puede decir que el propósito del cierre es este, extender el ciclo de vida de las variables locales. Después de que se ejecuta la función, las variables locales no pueden ser liberadas por la memoria, y luego el exterior puede acceder a la variable.

Volvamos al código anterior para analizarlo: el
código se está ejecutando

console.log(age);

El significado original de esta oración es que originalmente queríamos pedir 变量agesalida. Pero el resultado de la compilación informa de un error: la edad no está definida.
Esto se debe a que está 变量agedefinido en Clos()函数, y el alcance está limitado a la función Clos (). 变量ageEl equivalente Clos()函数a la propiedad privada (valor privado).

Entonces, si queremos llamar edad, ¿no hay manera?
En este momento, se refleja el papel del cierre. Clos()函数El valor de retorno apunta a 闭包函数getNum(). Debido a que está 闭包函数getNum()definido en Clos()函数, podemos usarlo para obtener 变量ageel valor. El cierre es equivalente a un método público (Método público) que se utiliza para proporcionar una interfaz con el mundo exterior para acceder a los datos internos.


Tres, las ventajas y desventajas de los cierres.

Déjame hablar primero de los inconvenientes.

También es debido al mecanismo de cierre que el mecanismo de recolección de basura de JavaScript no recuperará Clos()函数los recursos ocupados, porque las variables de las que depende la ejecución del cierre están en él. Si hay demasiados cierres en el código, provocará un desbordamiento de la memoria y afectará la carga de la página, así que tenga cuidado al utilizar cierres.

Echemos un vistazo a los beneficios.

Cuando JavaScript está desarrollando proyectos en colaboración con varias personas, si se definen demasiadas variables globales, puede causar conflictos de nombres de variables globales, que pueden resolverse bien mediante el uso de cierres.

    //公司程序员小李和小王一起协作开发项目
    var name = '小李';//小李定义了一个全局变量
    //var name = '小王'; //如果小王继续定义相同名字变量就会覆盖小李写的变量name的值
    
    var private = (function(){
    
    
        var name ='小王';
        function getName() {
    
    
            return name;
        }
        return getName;
    }());

    console.log("小王定义的name:"+private());
    console.log("小李定义的name:"+name);

En el código anterior, el primero se var name='小李'define en el ámbito global de la ventana. El segundo se var name = '小王'define en el cuerpo funcional, y el alcance no se afecta entre sí, lo que evita la contaminación global.


para resumir

Los cierres tienen principalmente las siguientes características:

  1. La función establece funciones, los cierres deben tener funciones anidadas. El propósito del cierre es acceder a las variables locales dentro de la función, si las variables locales no están definidas, no lograremos nuestro propósito, extender el ciclo de vida de la variable.

  2. La función externa debe tener una variable local y la función interna debe operar esta variable de la función externa.

  3. La función externa debe devolver la función interna al exterior, use return.

Al hacer el problema de cierre, también debemos prestar atención a los siguientes dos puntos:

  1. Cuando la función externa se llama varias veces, se creará un nuevo alcance, lo que significa que las variables locales de la función externa operada por la función interna no se verán afectadas
  2. La función interna devuelta por la función externa se llama varias veces, y las variables locales de la función externa operada por la función interna cambiarán varias veces.
//模拟了用户去银行存钱并查询余额的功能
function Person(name){
    
    
    var money = 0;
    function setMoney(m){
    
    
         money = m;
    }
    function getMoney(){
    
    
        return money;
    }
    return {
    
    
        name:name,
        setMoney:setMoney,
        getMoney:getMoney
    }
}

//第一次调用
var LiLei = person('李磊');
LiLei.setMoney(4500);//用户李磊存入4500元


//第二次调用
var WangWu = person('王武');
WangWu.setMoney(7000);//用户王武存入7000元

console.log(LiLei.getMoney());//得到并输出账户余额:4500
console.log(WangWu.getMoney());//得到并输出账户余额:7000
var LiLei = person('李磊');
var WangWu = person('王武');

Este código simula el proceso de apertura de una cuenta para dos usuarios diferentes que llaman a una función 变量moneypara modificar el valor de la operación . Debido a que cada llamada repetida abrirá un nuevo alcance, el dinero de Li Lei y Wang Wu no se depositará juntos. El dinero de Li Lei y Wang Wu se almacena en dos espacios de memoria diferentes.

Supongo que te gusta

Origin blog.csdn.net/qq_35370002/article/details/107885880
Recomendado
Clasificación