모의 개인 변수
개인 변수에 외부에서 접근할 수 없는 이유
루프의 클로저
참조 오류 방지
클로저는 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)를 참고해주세요!