>웹 프론트엔드 >JS 튜토리얼 >javascript_javascript 기술의 클로저에 대한 간략한 토론

javascript_javascript 기술의 클로저에 대한 간략한 토론

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB원래의
2016-05-16 15:59:251182검색

저는 오랫동안 클로저를 이해하지 못했습니다. 나중에 클로저 관련 지식을 이해하기 전에 범위와 이와 관련된 문제에 대해 배웠습니다.
종결은 또한 일반적인 인터뷰 질문입니다. 쉽게 말하면 함수 중첩 함수입니다.

반환 값 기능:

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");

위 내용은 이 글의 전체 내용입니다. 자바스크립트 클로저를 배우시는 모든 분들께 도움이 되었으면 좋겠습니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.