어떤 div를 클릭해도 4번째 div의 내용이 피드백됩니다. 그 이유는 각 div의 클릭 이벤트가 테스트 메소드와 클로저를 형성하고, 각 div의 클릭 이벤트가 동일한 클로저 범위 체인을 공유하기 때문입니다. 이벤트가 트리거되면 변수 i가 나타내는 아래 첨자는 이미 네 번째 div를 가리킵니다. 클로저로 인해 발생하는 문제를 방지하는 방법에는 여러 가지가 있습니다.
(1) 이를 사용하여 클로저의 범위 체인 컨텍스트를 변환합니다. 위 예제의 클로저는 다음과 같이 다시 작성할 수 있습니다. for (var i = 0; i {
var div = els[i];
div.onclick = function()
{
alert(this.innerHTML)
return false;
div를 클릭하는 이벤트가 발생하면 검색 범위는 이미 "this"에 지정된 컨텍스트입니다. 이벤트가 여전히 "테스트" 클로저 내에 있지만 클로저의 컨텍스트에 액세스하거나 사용되지 않으므로 클로저 범위의 변수가 참조되어 발생하는 문제는 없습니다.
(2) for 루프를 사용하여 div 양식을 클릭하는 이벤트를 클로저로 만들어 for 루프의 변수 div가 재활용되지 않도록 합니다. 예:
//for 루프에서 폐쇄 방법 정의
for (var i = 0; i { var div = els[i]
a(div);
함수 a(o)
{
o.onclick = function()
{
alert(o.innerHTML)
}
}
}
//for 루프 외부에서 폐쇄 방법 정의
for (var i = 0; i { var div = els[i]
a(div);
}
함수 a(o)
{
o.onclick = function()
{
alert(o.innerHTML)
}
}
//익명 메서드를 사용합니다. 원칙은 for 루프의 정의와 유사합니다.
for (var i = 0; i { var div = els [i]
(function(o)
{
o.onclick = function()
{
alert(o.innerHTML);
}
} )( div);
}
중간 메서드 또는 익명 메서드를 사용하여 for 루프 본문과 onclick 이벤트 사이에 클로저를 만듭니다.
(3) div를 클릭하는 이벤트에 필요한 변수가 외부 범위와 관련이 없도록 변수 범위를 제어합니다. 예:
for (var i = 0; i { (function()
{
var div = els[i];
div .onclick = function()
{
alert(div.innerHTML);
}
})();
}
내부 함수 자체에도 내부 함수가 있을 수 있습니다. 범위 체인이 중첩될 때마다 내부 함수 개체를 생성한 실행 환경으로 인해 새로운 활성 개체가 추가됩니다. ECMA262 사양에서는 범위 체인이 임시적이어야 하지만 범위 체인 길이에는 제한이 없습니다. 무언의 폐쇄 규칙은 함수와 내부적으로 정의된 함수 사이의 상호 작용 도메인 체인 컨텍스트 환경 간의 관계입니다. 올바르게 사용한다면 중첩된 내부 함수의 잠재력은 우리의 상상을 초월합니다.