클로저는 해당 기능의 기능 및 범위가 지정된 환경입니다.
이 경우 Java에서 범위를 구현하는 방법을 이해하는 데 도움이됩니다. 사실, 그것은 일련의 중첩 된 사전들입니다.
var global1 = "foo";
function myFunc() {
var x = 0;
global1 = "bar";
}
myFunc();
이 프로그램이 실행을 시작하면, 당신은 하나의 범위 사전을 가지고, 거기에 정의 된 여러 가지가있을 수 있습니다 글로벌 사전, :
{ global1: "foo", myFunc:<function code> }
당신이 MYFUNC를 호출 할 말이 코드를 고려 이것은 로컬 변수 x를가집니다. 이 함수의 실행을 위해 새 범위가 만들어집니다. 함수의 로컬 범위는 다음과 같습니다.
{ x: 0 }
또한 상위 범위에 대한 참조를 포함합니다. 따라서 함수의 전체 범위는 다음과 같습니다.
{ x: 0, parentScope: { global1: "foo", myFunc:<function code> } }
이렇게하면 myFunc에서 global1을 수정할 수 있습니다. Javascript에서는 변수에 값을 할당하려고 할 때마다 변수 이름의 로컬 범위를 먼저 확인합니다. 발견되지 않으면 변수가 발견 될 때까지 parentScope 및 해당 범위의 parentScope 등을 검사합니다.
클로저는 말 그대로 함수의 범위 (부모 범위에 대한 포인터를 포함하는 등)에 대한 포인터를 더한 함수입니다. for
루프가 실행이 완료된 후에 그래서, 당신의 예에서, 범위는 다음과 같습니다
setupHelpScope = {
helpText:<...>,
i: 3,
item: {'id': 'age', 'help': 'Your age (you must be over 16)'},
parentScope: <...>
}
이 하나의 범위 객체를 가리 킵니다 만들 때마다 폐쇄. 우리가 만든 모든 폐쇄를 나열한다면, 그것은 다음과 같이 보일 것입니다 :
[anonymousFunction1, setupHelpScope]
[anonymousFunction2, setupHelpScope]
[anonymousFunction3, setupHelpScope]
이러한 기능 중 하나가, 그것이 전달하는 범위 개체를 사용하여 실행할 때 -이 경우는, 동일한 범위의 각 기능에 대한 객체! 각각은 동일한 item
변수를보고 동일한 값을 보게되며 이는 for
루프에 의해 설정된 마지막 값입니다.
질문에 대답하려면 var item
을 루프에 넣거나 그 안에 넣을지는 중요하지 않습니다. for
루프는 자체 범위를 만들지 않으므로 item
은 현재 함수의 범위 사전 인 setupHelpScope
에 저장됩니다. for
루프 내부에서 생성 된 인클로저는 항상 setupHelpScope
을 가리 킵니다.
몇 가지 중요한 사항 : 자바 스크립트, for
루프가 자신의 범위를하지 않아도 때문에이 문제가 발생
- - 그들은 단지 바깥 쪽 함수의 범위를 사용합니다.
if
, while
, switch
등의 경우에도 마찬가지입니다. 반면 C# 인 경우 각 루프에 대해 새 범위 개체가 만들어지고 각 클로저에는 고유 한 범위에 대한 포인터가 포함됩니다.
anonymousFunction1
이 해당 범위의 변수를 수정하는 경우 다른 익명 함수의 해당 변수를 수정한다는 점에 유의하십시오. 이것은 몇몇 기이 한 상호 작용을 일으킬 수 있습니다.
- 범위는 사용자가 프로그래밍하는 것과 같은 개체입니다. 구체적으로 사전입니다. JS 가상 머신은 가비지 컬렉터를 사용하여 메모리에서 삭제 작업을 관리합니다. 이러한 이유 때문에 클로저를 과도하게 사용하면 실제 메모리가 부풀어 오를 수 있습니다. 클로저에는 스코프 객체에 대한 포인터가 포함되어 있으므로 (이는 상위 범위 객체에 대한 포인터를 포함하고 있음) 전체 스코프 체인을 가비지 수집 할 수 없으므로 메모리에 고수해야합니다.
추가 읽기 :
자바 스크립트에'let'이 있습니까? look up ... – Kobi
@Kobi : Mozilla에만 국한된 JavaScript 확장 기능입니다. [this] (https://developer.mozilla.org/en/new_in_javascript_1.7)를 참조하십시오. –
Mozilla에만 해당되는 경우 사용하지 말아야합니까? – Nick