Leve você a entender os fechamentos mais autênticos e fáceis de entender, a mãe não tem mais medo do entrevistador fazer perguntas

Entendendo os fechamentos

Pano ofuscado

Primeiro, o que é um fechamento? Você pode entendê-lo como compartilhando variáveis ​​em dois escopos desconectados.
Dê uma castanha:

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

Você notou que as variáveis ​​dentro da função foo são usadas abaixo do escopo global, este é o encerramento! ! !

O escopo da barra de funções abrange a função foo. Passamos a referência da função bar como valor de retorno e, em seguida, podemos usar a referência da função foo na referência.

A mágica do fechamento em si não está aqui.De um modo geral, o escopo de foo é coletado pelo coletor de lixo após a execução da função foo ser concluída, mas não está aqui, porque ainda há uma referência ao escopo de foo. Desmaiado, ou seja, bar, bar possui um ponteiro para a variável a, portanto, o escopo de foo não é recuperado após a utilização da função foo. bar ainda mantém uma referência ao escopo de foo, que é chamado de fechamento.

Há também uma variedade de fechamentos de funções.

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

Talvez depois que você entenda, o fechamento é apenas um brinquedo um pouco estranho, mas o que eu quero dizer é que o fechamento não é apenas uma maneira de escrever, e várias situações são usadas na vida cotidiana:

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

O escopo interno do timer não desaparece após 1000 milissegundos e, em seguida, contém uma referência à mensagem.

2. Loops e fechamentos

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

No meu outro pequeno ponto de conhecimento no front-end, mencionei que há uma promoção variável aqui, e ela será impressa toda vez 6. Uma pequena explicação, porque após o atraso da função, irei à pesquisa RHS para a referência de i. i = 6, originalmente queríamos capturar uma cópia de i em cada iteração, mas cada iteração é um escopo compartilhado, portanto, encontramos apenas 6;
se modificarmos o código, adicionando o princípio do escopo, Vamos tentar:

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

Está tudo bem? Ha ha ha ha, ainda não funciona, porque nosso escopo lexical está vazio, precisamos estabelecer um atributo privado para ele.

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

Tudo bem, porque eu aponto para o escopo interno j de cada função anônima interna!
Embeleze este código:

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

Obviamente, se você deseja concluir a lógica de forma mais concisa, pode usar

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

Módulo

Depois de entender os fechamentos, vamos entender como usar os fechamentos em geral.

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 é o uso de módulos.
Fonte de idéias para este blog: (NOVO) [美] -Kyle-Simpson-JavaScript que você não conhece (volume 1)

Publicado 20 artigos originais · ganhou elogios 5 · Vistas 2075

Acho que você gosta

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