저는 오랫동안 클로저를 이해하지 못했습니다. 나중에 클로저 관련 지식을 이해하기 전에 범위와 이와 관련된 문제에 대해 배웠습니다.
종결은 또한 일반적인 인터뷰 질문입니다. 쉽게 말하면 함수 중첩 함수입니다.
반환 값 기능:
function foo () { var a = 1; return function () { a++; console.log(a); } } var aaa = foo(); aaa(); //2 aaa(); //3
사실 이 코드는 이해하기 어렵지 않습니다. aaa는 foo()가 반환한 새로운 함수를 가리키지만 이 함수에서는 a 변수가 참조되므로 foo 함수가 실행될 때 변수 a가 여전히 존재합니다. 메모리가 해제되지 않습니다. 즉, a는 각각 2와 3이다.
매개변수로서의 기능:
var a = 10; function foo () { console.log(a); } function aaa(fn) { var a = 100; fn(); } aaa(foo);
이전 이해에 따르면 fn 함수가 aaa 함수에서 실행될 때 변수가 없으면 상위 범위로 이동하여 a 변수를 찾으십시오. 여기서는 100입니다. 결과는 100입니까?
안타깝게도 대답은 '아니요'입니다. 결과는 10입니다. Wang Fupeng 선생님의 블로그에서는 "상위 범위" 대신 이 함수의 범위 값을 만들어야 한다고 말했습니다.
폐쇄 사용 시나리오
저는 아직 초보이기 때문에 여기서는 간단한 예를 들어보겠습니다. li를 클릭하면 index 값인 ul에서 li의 위치가 팝업됩니다.
html 코드:
<ul> <li>001</li> <li>002</li> <li>003</li> </ul>
js 코드:
예 1:
아래 코드를 실행해 보면 어떤 li를 클릭해도 결과가 3이라는 것을 알 수 있습니다.
var aLi = document.getElementsByTagName('li'); for (var i = 0; i<aLi.length; i++) { aLi[i].onclick = function() { alert(i); } }
익명 함수에는 i 변수가 없기 때문에 종료 시 페이지의 li 태그를 클릭하면 이때 i는 이미 3입니다.
예 2:
aLi[i].onclick = (function(i){ return function(){ alert(i); } })(i);
이번 방법은 함수를 반환 값으로 사용하고, 자체 실행 함수의 매개 변수를 통해 변수 i를 전달하는 것입니다. 그러면 반환 함수는 i 변수를 참조하므로 i 변수는 그렇지 않습니다. for 루프가 끝나면 해제됩니다. 즉, i 변수의 값이 메모리에 저장된다. 이 원칙에 따르면 낮은 버전의 IE에서는 메모리 누수가 발생하기 쉽습니다.
예 3:
for (var i = 0; i<aLi.length; i++) { (function(i){ aLi[i].onclick = function(){ alert(i); } })(i); }
이 원리는 위와 비슷합니다.
Xiaomi 프런트엔드 폐쇄 인터뷰 질문:
function repeat (func, times, wait) { } //这个函数能返回一个新函数,比如这样用 var repeatedFun = repeat(alert, 10, 5000) //调用这个 repeatedFun ("hellworld") //会alert十次 helloworld, 每次间隔5秒
내 답변:
function repeat (func, times, wait) { return function(str) { while (times >0) { setTimeout(function(){ func(str); },wait); times--; } } } var repeatedFun = repeat(alert, 10, 100); repeatedFun ("hellworld");
위 내용은 이 글의 전체 내용입니다. 자바스크립트 클로저를 배우시는 모든 분들께 도움이 되었으면 좋겠습니다.