Comprensión integral de los cierres de Javascript.

que es el cierre

Cierre, la explicación oficial del cierre es: una expresión (generalmente una función) que tiene muchas variables y un entorno vinculado a estas variables, por lo que estas variables también son parte de la expresión. Características de los cierres:

  1. Como referencia a una variable de función, está activa cuando la función regresa.
  2. Un cierre es un área de la pila que no libera recursos cuando regresa una función.

En pocas palabras, Javascript permite el uso de funciones internas, es decir, definiciones de funciones y expresiones de funciones ubicadas dentro del cuerpo de la función de otra función. Además, estas funciones internas tienen acceso a todas las variables locales, parámetros y otras funciones internas declaradas en la función externa en la que existen. Un cierre se forma cuando una de estas funciones internas se llama fuera de la función externa que las contiene.

Varias formas de escribir cierres

  1. Agregue algunas propiedades a la función.
//第1种写法  
function Circle(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);     
alert(c.area());
  1. Asignar una función como valor a una variable
//第2种写法  
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();  
alert( c.area( 1.0 ) );
  1. La mejor manera de entender este método es crear un nuevo objeto y luego agregar propiedades y métodos al objeto.
//第3种写法  
var Circle = new Object();  
Circle.PI = 3.14159;  
Circle.Area = function( r ) {
    
      
       return this.PI * r * r;  
}  
alert( Circle.Area( 1.0 ) );
  1. Este método se utiliza con más frecuencia y es el más conveniente. var obj = {} declara un objeto vacío
//第4种写法  
var Circle={
    
      
   "PI":3.14159,  
   "area":function(r){
    
      
       return this.PI * r * r;  
    }  
};  
alert( Circle.area(1.0) );
  1. Nunca he usado esta forma de escribir y no es fácil de entender, puedes aprender más al respecto.
//第5种写法  
var Circle = new Function("this.PI = 3.14159;this.area = function( r ) {return r*r*this.PI;}");  
  
alert( (new Circle()).area(1.0) );  
En general, entre los métodos anteriores, el segundo y cuarto método son los más comunes y puedes elegir según tus hábitos.

El propósito de los cierres de Javascript

  1. Función autoejecutable anónima
    Sabemos que todas las variables, si no agrega la palabra clave var, se agregarán a las propiedades del objeto global de forma predeterminada. Agregar dichas variables temporales al objeto global tiene muchas desventajas, tales como: otras funciones puede hacer un mal uso
    de estas variables, lo que hace que el objeto global sea demasiado grande y afecte la velocidad de acceso (porque el valor de la variable debe atravesarse desde la cadena del prototipo).
    Además de usar la palabra clave var cada vez que se usa una variable, a menudo nos encontramos con una situación de este tipo en situaciones reales, es decir, algunas funciones solo necesitan ejecutarse una vez y no es necesario mantener sus variables internas, como la interfaz de usuario. inicialización, entonces podemos
    usar Cierre:
var data= {
    
        
    table : [],    
    tree : {
    
    }    
};    
     
(function(dm){
    
        
    for(var i = 0; i < dm.table.rows; i++){
    
        
       var row = dm.table.rows[i];    
       for(var j = 0; j < row.cells; i++){
    
        
           drawCell(i, j);    
       }    
    }    
       
})(data);
//ES5里的var没有块状作用域
//ES5里只有函数才有作用域的概念,通过闭包解决i的作用域问题
for(var i=0;i<3;i++){
    
    
	(function(i){
    
    
		btn[i].addEventListener('click',function(){
    
    
			//处理逻辑
		})
	})(i);
}

//ES6里的let具有块状作用域,每次循环的i都具有独立的空间
//而这种写法var是做不到的,var以最后一次循环i=2作为所有事件最终处理逻辑
for(let i=0;i<3;i++){
    
    
	btn[i].addEventListener('click',function(){
    
    
		//处理逻辑
	})
}

Creamos una función anónima y la ejecutamos inmediatamente. Dado que no se puede hacer referencia a sus variables internas desde el exterior, los recursos se liberarán inmediatamente después de que se ejecute la función. La clave es no contaminar el objeto global.

  1. En el desarrollo de la caché de resultados
    , a veces es necesario almacenar el valor calculado. Al llamar a esta función, primero busca en la caché. Si no se encuentra, realiza el cálculo, luego actualiza la caché y devuelve el valor. Si se encuentra, regresa directamente a la búsqueda al valor. Los cierres pueden hacer esto porque no liberan referencias externas, por lo que se pueden conservar los valores dentro de la función.
var CachedSearchBox = (function(){
    
        
    var cache = {
    
    },count = [];    
    return {
    
        
       attachSearchBox : function(dsid){
    
        
           if(dsid in cache){
    
    //如果结果在缓存中    
              return cache[dsid];//直接返回缓存中的对象    
           }    
           var fsb = new uikit.webctrl.SearchBox(dsid);//新建    
           cache[dsid] = fsb;//更新缓存    
           if(count.length > 100){
    
    //保正缓存的大小<=100    
              delete cache[count.shift()];    
           }    
           return fsb;          
       },    
       clearSearchBox : function(dsid){
    
        
           if(dsid in cache){
    
        
              cache[dsid].clearSelection();      
           }    
       }    
    };    
})();    
CachedSearchBox.attachSearchBox("input");
  1. encapsulación
var person = function(){
    
        
    //变量作用域为函数内部,外部无法访问    
    var name = "default";       
    return {
    
        
       getName : function(){
    
        
           return name;    
       },    
       setName : function(newName){
    
        
           name = newName;    
       }    
    }    
}();    
print(person.name);//直接访问,结果为undefined    
print(person.getName());    
person.setName("abruzzi");    
print(person.getName());    
   
得到结果如下:  

undefined  
default  
abruzzi
var mymath = (function () {
    
    
	var counter = 0;
	return  {
    
    
		myadd:function(){
    
    
			return counter += 1;
		},
		mydeduct:function(){
    
    
			return counter -= 1;
		}
	}
})();
function add(){
    
    
	document.getElementById("demo").innerHTML = mymath.myadd();
}
function deduct(){
    
    
	document.getElementById("demo").innerHTML = mymath.mydeduct();
}
  1. Implementación de clases y herencia.
function Person(){
    
        
    var name = "default";       
    return {
    
        
       getName : function(){
    
        
           return name;    
       },    
       setName : function(newName){
    
        
           name = newName;    
       }    
    }    
};   

var p = new Person();
p.setName("Tom");
alert(p.getName());
var Jack = function(){
    
    };
//继承自Person
Jack.prototype = new Person();
//添加私有方法
Jack.prototype.Say = function(){
    
    
    alert("Hello,my name is Jack");
};
var j = new Jack();
j.setName("Jack");
j.Say();
alert(j.getName());

Supongo que te gusta

Origin blog.csdn.net/wo240/article/details/112876821
Recomendado
Clasificación