JavaScript 고급 시리즈 - 클로저 및 참조

黄舟
풀어 주다: 2017-02-08 09:46:08
원래의
1060명이 탐색했습니다.
  • 모의 개인 변수

  • 개인 변수에 외부에서 접근할 수 없는 이유

  • 루프의 클로저

  • 참조 오류 방지

클로저는 JavaScript의 매우 중요한 기능으로, 현재 범위가 항상 외부 범위 변수에 액세스할 수 있다는 의미입니다. 함수는 자체 범위를 갖는 JavaScript의 유일한 구조이기 때문에 클로저 생성은 함수에 의존합니다.

개인 변수 시뮬레이션

function Counter(start) {
    var count = start;
    return {
        increment: function() {
            count++;
        },

        get: function() {
            return count;
        }
    }
}

var foo = Counter(4);
foo.increment();
foo.get(); // 5
로그인 후 복사

여기서 Counter 함수는 두 개의 클로저인 increment 함수와 get 함수를 반환합니다. 두 함수 모두 외부 범위 Counter에 대한 참조를 유지하므로 이 범위 내에 정의된 변수 count에 항상 액세스할 수 있습니다.

왜 비공개 변수에 외부에서 접근할 수 없나요?

자바스크립트에서는 범위를 참조하거나 할당할 수 없기 때문에 외부에서 count 변수에 접근할 방법이 없습니다. 유일한 방법은 두 개의 클로저를 통하는 것입니다.

var foo = new Counter(4);
foo.hack = function() {
    count = 1337;
};
로그인 후 복사

위 코드는 foo.hack이 해당 범위에 정의되어 있지 않기 때문에 Counter 범위에 정의된 count 변수의 값을 변경하지 않습니다. 전역 변수 개수를 생성하거나 덮어씁니다.

루프의 클로저

루프에서 클로저를 사용할 때 흔히 발생하는 실수는 각 루프에서 루프 시퀀스 번호를 호출해야 한다고 가정해 보겠습니다.

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i);  
    }, 1000);
}
로그인 후 복사

위 코드는 다음과 같습니다. 0부터 9까지의 숫자는 출력하지 않고 숫자 10을 10번 출력합니다.

console.log가 호출되면 익명 함수는 외부 변수 i에 대한 참조를 유지합니다. 이때 for 루프가 종료되고 i 값이 10으로 수정되었습니다.

원하는 결과를 얻으려면 각 루프에서 변수 i의 복사본을 만들어야 합니다.


참조 오류 방지

루프 시퀀스 번호를 올바르게 얻으려면 익명 래퍼를 사용하는 것이 가장 좋습니다(번역자 주: 실제로는 우리가 일반적으로 자체 실행 익명 함수라고 부르는 것입니다.

for(var i = 0; i < 10; i++) {
    (function(e) {
        setTimeout(function() {
            console.log(e);  
        }, 1000);
    })(i);
}
로그인 후 복사

외부 익명 함수는 즉시 실행되며 i를 매개변수로 사용합니다. 이때 함수의 e 변수는 i의 복사본을 갖게 됩니다.

setTimeout에 전달된 익명 함수가 실행되면 e에 대한 참조가 있으며 이 값은 루프에 의해 변경되지 않습니다.

동일한 작업을 수행하는 또 다른 방법이 있는데, 그것은 익명 래퍼에서 함수를 반환하는 것입니다. 이는 위의 코드와 동일한 효과를 갖습니다.

for(var i = 0; i < 10; i++) {
    setTimeout((function(e) {
        return function() {
            console.log(e);
        }
    })(i), 1000)
}
로그인 후 복사

위는 JavaScript 고급 시리즈의 내용입니다 - 클로저 및 참고자료 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿