Llevarte a comprender los cierres más auténticos y fáciles de entender, mamá ya no teme que el entrevistador haga preguntas

Comprender los cierres

Paño ensombrecido

Primero, ¿qué es un cierre? Puede entenderlo como compartir variables en dos ámbitos desconectados.
Dar una castaña:

function foo() {
	var a = 10;
	function bar () {
		console.log(a);
	}
	return bar;
}
foo()();// 10 请注意这里的10怎么来的。

¿Has notado que las variables dentro de la función foo se usan debajo del alcance global, este es el cierre! ! !

El alcance de la barra de funciones cubre la función foo. Pasamos la referencia de la función de barra como el valor de retorno, y luego podemos usar la referencia de función de foo en la referencia.

La magia del cierre en sí no está aquí. En términos generales, el recolector de basura recolecta el alcance de foo después de que se completa la ejecución de la función foo, pero no está aquí, porque hay una referencia al alcance de foo. Desmayado, es decir, bar, bar tiene un puntero a la variable a, por lo que el alcance de foo no se recupera después de utilizar la función foo. bar todavía tiene una referencia al alcance de foo, que se llama cierre.

También hay una variedad de cierres de funciones.

function foo() {
	var a = 2;
	function baz() {
	console.log( a ); // 2
}
	bar( baz );
}
function bar(fn) {
	fn(); // 妈妈快看呀,这就是闭包!
}

Tal vez después de que lo entiendas, el cierre es solo un juguete un poco extraño, pero lo que quiero decir es que el cierre no es solo una forma de escribir, y se usan varias situaciones en la vida diaria:

function wait(message) {
	setTimeout( function timer() {
		console.log( message );
	}, 1000 );
}
wait( "Hello, closure!" );

El alcance interno del temporizador no desaparece después de 1000 milisegundos, y luego contiene una referencia al mensaje.

2. Bucles y cierres.

for (var i=1; i<=5; i++) {
	setTimeout( function timer() {
		console.log( i );
	}, i*1000 );
}

En mi otro pequeño punto de conocimiento en el front-end, mencioné que hay una promoción variable aquí, e imprimirá 6. Cada vez. Una pequeña explicación, porque después del retraso de la función, iré a la búsqueda de RHS para encontrar la referencia de i. i = 6, originalmente queríamos capturar una copia de i en cada iteración, pero cada iteración es un alcance compartido, por lo que todo lo que encontramos es 6;
si modificamos el código agregando el principio de alcance, Probemos

for (var i = 0; i < 5; i++) {
	(function () {
		setTimeout( function timer() {
			console.log( i );
		}, i*1000 );
	})();
}

¿Está todo bien? Ja, ja, ja, ja, aún no funciona, porque nuestro ámbito léxico está vacío, tenemos que establecer un atributo privado para él.

for (var i = 0; i < 5; i++) {
		(function () {
			var j = i;
			setTimeout( function timer() {
				console.log( j );
			}, j*1000 );
		})();
	}

¡Esto está bien, porque apunta al alcance interno j de cada función anónima interna!
Embellecer este código:

	for (var i = 0; i < 5; i++) {
		(function (j) {
			setTimeout( function timer() {
				console.log( j );
			}, j*1000 );
		})(i);
	}

Por supuesto, si desea completar la lógica de manera más concisa, puede usar let

for (let i = 0; i < 5; i++) {
	setTimeout( function timer() {
		console.log( i );
	}, i*1000 );
}

Modulo

Después de comprender los cierres, comprendamos cómo usarlos en general.

function Car() {
	var name = "五菱宏光";
	var age = "2 年";	

	function sayName () {
		console.log(name);
	}

	function sayAge () {
		console.log(age);
	}
	function drive () {
		console.log('drived');
    }
    
    return {
        sayName: sayName,
        sayAge: sayAge,
        drive: drive
    }
}

var car = Car();
car.sayName();

Este es el uso de módulos.
Fuente de ideas para este blog: (NUEVO) [美] -Kyle-Simpson-JavaScript que no conoce

Publicado 20 artículos originales · ganado elogios 5 · Vistas 2075

Supongo que te gusta

Origin blog.csdn.net/qq_42859887/article/details/105348870
Recomendado
Clasificación