독립적인 객체로서의 범위와 함수의 기본 개념을 잘 이해하고 있다면 클로저의 개념을 이해하고 실제 프로그래밍 실습에 적용하는 것은 꽤 쉬울 것입니다.
DOM 이벤트 처리 측면에서 대부분의 프로그래머는 이미 클로저를 사용하고 있습니다. 이 경우 브라우저에 내장된 JavaScript 엔진의 버그로 인해 메모리 누출 문제가 발생할 수 있습니다. 디버깅할 때 종종 혼란스러워집니다.
간단한 문장을 사용하여 JavaScript의 클로저 개념을 설명합니다. JavaScript에서 함수는 객체이고 객체는 속성의 모음이며 속성의 값은 객체가 될 수 있으므로 다음과 같이 정의하는 것이 자연스럽습니다. 함수 내의 함수 func 내부에 함수를 선언한 다음 함수 외부에서 inner를 호출하면 클로저가 생성됩니다.
클로저의 특성:
먼저 예제를 살펴보겠습니다. JavaScript의 특성을 이해하지 못하면 이유를 찾기가 어렵습니다.
var outter = [];
function clouseTest() {
var array = ["1", " 2", "3", "4"];
for (var i = 0; i < array.length; i ) {
var x = {};
x.no = i;
Outter.push(x);
}
}
> ~ ; 많은 초보자들이 다음과 같은 대답을 할 수 있습니다:
0
1
2
3
그러나 이 프로그램을 실행하면 결과는 다음과 같습니다.
4
4
4
4
실제로 각 반복마다 x.invoke = function(){print(i);} 문은 실행되지 않고 함수 개체만 구성합니다. 함수 본문에 "print(i);"가 있으면 그게 전부입니다. i=4이면 반복이 중지되고 외부 함수가 반환됩니다. external[0].invoke()가 다시 호출되면 i 값은 여전히 4이므로 외부 배열의 각 요소를 호출하면 i 값이 반환됩니다. . :4. 이 문제를 해결하는 방법? 익명 함수를 선언하고 즉시 실행할 수 있습니다.
코드 복사
코드는 다음과 같습니다.
var outter = [];
function clouseTest2() {
var array = ["one", "two", " three", "four"];
for (var i = 0; i < array.length; i ) {
var x = {};
x.no = i;
x.text = array[i];
x .invoke = 기능(아니요) {
;
outter.push(x);
}
}
clouseTest2();
이 예에서는 x.invoke에 값을 할당할 때 먼저 함수를 반환할 수 있는 함수를 실행한 다음 즉시 실행합니다. 이런 식으로 x.invoke의 각 반복자는 다음과 같은 문을 실행하는 것과 같습니다. 이:
x.invoke = function(){print(0);}
//x == 1
x.invoke = function(){print(1);}
//x = = 2
x.invoke = function(){print(2);}
//x == 3
x.invoke = function(){print(3);}
이렇게 하면 올바른 결과를 얻을 수 있습니다. 클로저를 사용하면 외부 함수 내에 존재하는 변수를 참조할 수 있습니다. 그러나 변수가 생성되었을 때의 값을 사용하지 않고 대신 외부 함수에서 변수의 마지막 값을 사용합니다.
폐쇄의 목적:
이제 폐쇄의 개념이 명확해졌으니, 폐쇄의 목적을 살펴보겠습니다. 실제로 클로저를 사용하면 많은 일을 할 수 있습니다. 예를 들어, 객체 지향 코딩 스타일을 시뮬레이션할 수 있으며, 코드를 더욱 우아하고 간결하게 표현하고 일부 측면에서 코드의 실행 효율성을 향상시킵니다.
캐시:
또 다른 예를 살펴보겠습니다. 처리 시간이 매우 오래 걸리는 함수 개체가 있다고 가정해 보겠습니다. 계산 나오는 값은 저장되며, 이 함수가 호출되면 먼저 캐시에서 검색하여 찾지 못한 경우에는 캐시를 업데이트하고 찾은 경우 해당 값을 반환합니다. 찾은 값이 직접 반환됩니다.
클로저는 외부 참조를 해제하지 않고 함수 내부의 값을 유지할 수 있기 때문에 정확하게 이를 수행할 수 있습니다.