>웹 프론트엔드 >JS 튜토리얼 >JavaScript 클로저에 대한 쉬운 이해

JavaScript 클로저에 대한 쉬운 이해

黄舟
黄舟원래의
2017-03-20 14:48:572127검색

클로저 메커니즘은 자바스크립트의 핵심이자 난이도입니다. 이 글을 통해 모든 사람이 클로저를 쉽게 배울 수 있기를 바랍니다. 아래 에디터로 살펴보겠습니다

Abstract

Javascript의 핵심이자 난이도는 클로저 메커니즘을 누구나 쉽게 배울 수 있도록 돕기 위한 글입니다

1. 클로저란?

클로저는 다른 함수 범위에 있는 변수에 액세스할 수 있는 함수입니다.

다음은 일반적인 클로저 구현 방법과 클로저의 개념을 예시로 설명합니다

function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999
  nAdd();
  result(); // 1000

f1은 f2의 상위 함수이고, f2는 전역 변수(return 값)에 할당됩니다. 결과적으로 f2는 항상 메모리에 있고 f2의 존재는 f1에 따라 달라지므로 f1은 항상 메모리에 있으며 호출이 완료된 후 가비지 수집 메커니즘(가비지 수집)에 의해 재활용되지 않으며 클로저를 형성합니다.

그러니까 이렇게 이해하시면 됩니다. 함수 A 가 다른 함수 B의 변수를 참조하지만 B가 반환된 후에도 A가 여전히 반환하지 않는 경우 A의 참조로 인해 B의 모든 변수가 여전히 존재한다는 것입니다. 지역 변수는 B을 종료할 때 로그아웃되지 않으며, A가 로그아웃할 때까지 존재합니다. 이때 A는 클로저입니다.

2. 클로저의 this 포인터

클로저는 일반적으로 전역 환경에서 호출되므로 이는 일반적으로 창을 가리킵니다. 특정 상황에서는 여전히 필요합니다. 실행 환경에 따라 간단히 말해서 실행 환경을 가리킵니다.

클로저의 this가 포함된 객체 를 가리켜야 하는 경우 포함 객체의 this를 변수로 클로저에 전달해야 합니다.

3. 클로저 사용 시 주의사항

  1. 클로저를 사용하면 함수의 변수가 메모리에 저장되므로 메모리 소모가 심합니다. 매우 크기 때문에 클로저를 남용할 수 없습니다. 그렇지 않으면 웹 페이지에서 성능 문제를 일으키고 IE에서 메모리 누수를 일으킬 수 있습니다. 해결책은 함수를 종료하기 전에 사용하지 않는 모든 지역 변수를 삭제하는 것입니다.

  2. 클로저는 상위 함수 외부의 상위 함수 내부 변수 값을 변경합니다. 따라서 상위 함수를 객체(객체)로 사용하고 클로저를 공개 메소드(Public Method)로 사용하며 내부 변수를 비공개 속성(비공개 값)으로 사용하는 경우 , 부모 함수의 내부 변수 값을 임의로 변경하지 않도록 주의해야 합니다.

4. 일반적인 종결 면접 질문 해결

질문:

function onMyLoad(){
  /*
  抛出问题:
  此题的目的是想每次点击对应目标时弹出对应的数字下标 0~4,但实际是无论点击哪个目标都会弹出数字5
  问题所在:
  arr 中的每一项的 onclick 均为一个函数实例(Function 对象),这个函数实例也产生了一个闭包域,
  这个闭包域引用了外部闭包域的变量,其 function scope 的 closure 对象有个名为 i 的引用,
  外部闭包域的私有变量内容发生变化,内部闭包域得到的值自然会发生改变
  */
  var arr = document.getElementsByTagName("p");
  for(var i = 0; i < arr.length;i++){
  arr[i].onclick = function(){
   alert(i);
  }
  }
 }

해결책

1. 외부에 함수 레이어를 추가하고 i를 함수 매개변수로 전달하여 모든 What이 저장되도록 합니다. 이번에는 함수 내부의 변수로, 외부 i와 동일한 메모리 공간에 있지 않습니다. 함수가 호출될 때마다 지역 변수가 생성되므로 매번 저장되는 값이 변하지 않음을 보장할 수 있습니다. 서로 영향을 미칩니다.

for(var i = 0; i<arr.length;i++){
 arr[i].onclick = (function(arg){
  return function () {
   alert(arg);
  }
 })(i);
}

2. 새로운 ES6 let을 사용하여 for 루프의 var i를 let i로 변경하여 현재 i가 이 주기에서만 유효하도록 합니다. 사이클은 실제로는 모두 새로운 변수입니다. 루프의 각 주기에서 변수 i가 다시 선언되면 어떻게 이전 주기의 값을 알고 현재 주기의 값을 계산하는지 물어볼 수 있습니다. 이는 자바스크립트 엔진이 내부적으로 이전 주기의 값을 기억하고 있으며, 이번 주기의 변수 i를 초기화할 때 이전 주기를 기준으로 계산이 이루어지기 때문이다.

위 내용은 JavaScript 클로저에 대한 쉬운 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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