범위 할당 및 변수 접근 규칙
ECMAScript에서는 함수도 객체입니다. 함수 개체는 변수 인스턴스화 중 함수 선언에서 생성되거나 함수 표현식이 평가되거나 Function 생성자가 호출될 때 생성됩니다. ('함수 객체'에 대한 자세한 내용은 "Javascript_08_함수 객체 이해"를 참조하세요.) 모든 함수 객체에는 객체 목록(체인)으로 구성된 내부 [[scope]] 속성이 있습니다. 내부 [[scope]] 속성은 생성된 실행 환경의 범위 체인을 참조하며, 현재 실행 환경의 활성 개체가 개체 목록의 맨 위에 추가됩니다. 함수 내부의 변수에 액세스하는 것은 실제로 범위 체인에서 변수를 찾는 프로세스입니다.
너무 이론적입니다(결국 요약!). 코드 일부를 살펴보겠습니다.
다음 그림은 위 코드의 메모리 할당과 범위 할당을 명확하게 보여줍니다.
아래에서 설명하겠습니다.
1. 코드를 로드하고 전역 실행 환경을 생성합니다. 이때 변수 개체(창)에 외부 변수가 추가됩니다. 함수 객체를 가리키는 외부, 현재 범위 체인에는 창 객체만 있습니다.
2. 프로그램이 외부()를 실행하면 전역에서 외부 변수를 찾습니다. 이의를 제기하고 성공적으로 호출합니다. 3.outer의 실행 환경을 생성합니다. 이때 새로운 활성 객체가 생성되고, 변수 i를 추가하고, 값을 10으로 설정하고, inner 변수를 추가하고, 활성 객체를 push합니다. 그리고 외부에 있는 함수 객체의 [[scope]] 속성을 활성 객체 외부에 지정합니다. 이때 범위 체인은 외부의 활성 개체 창입니다.
4. 코드를 실행하고 i에 값을 성공적으로 할당합니다. 프로그램이 inner()를 실행할 때, 함수 객체 external의 [[scope]]에서 내부 변수를 찾습니다. 찾은 후 성공적으로 호출되었습니다.
5. inner의 실행 환경을 만들고, 새로운 활성 개체를 만들고, 변수 j를 추가하고, 값을 100으로 할당하고, 활성 개체를 범위 체인에 푸시하고, 함수의 [[scope]] 속성을 가리킵니다. 내부 객체는 활성 객체 내부입니다. 이때 범위 체인은 내부의 활성 객체와 외부의 활성 객체 전역 객체입니다.
6. 실행 코드는 i와 j에 액세스할 때 해당 값을 할당합니다. 범위 및 출력에서 성공적으로 발견되었으며, adf 변수에 액세스할 때 범위에서 발견되지 않아 액세스 오류가 발생했습니다.
참고: 메모리 그래프를 통해 스코프 체인과 프로토타입 체인이 매우 유사하다는 것을 알 수 있습니다. 이것은 많은 문제를 설명합니다... (자비롭고 지혜롭게 답을 스스로 찾아보세요!)
폐쇄의 원리
범위의 문제를 이해하고 나면 종결의 문제는 이미 매우 단순한 . 폐쇄란 무엇입니까? 클로저는 외부 함수의 범위에 있는 변수를 둘러싸는 내부 함수입니다.
일반적인 클로저 애플리케이션을 살펴보겠습니다: 증분 값 생성
>
외부 익명 함수는 인라인 함수를 반환하고, 인라인 함수는 외부 익명 함수의 지역 변수 id를 사용합니다. 논리적으로 말하면, 외부 익명 함수의 지역 변수는 반환될 때 범위를 벗어나므로 increment() 호출을 사용할 수 없습니다. 이것이 클로저입니다. 즉, 함수 호출이 포함된 함수를 반환하고, 포함된 함수는 닫혀야 하는 외부 함수의 지역 변수, 매개변수 및 기타 리소스를 참조합니다(Close). 무슨 일이야? 답을 찾아봅시다:
스코프 체인에 대한 이해에 따르면, 반환된 인라인 함수는 생성 당시 이미 스코프 체인을 보유하고 있다고 설명할 수 있습니다. 그러나 외부 반환으로 인해 이러한 개체가 밖으로 나가게 됩니다. 범위는 수명 범위이지만 JavaScript는 자동 가비지 수집을 사용하여 객체 메모리를 해제합니다. 규칙에 따라 주기적으로 확인되며 참조가 없는 경우에만 객체가 해제됩니다. 따라서 위의 코드는 올바르게 실행됩니다.
http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-Model-Execution-Model.html
http://www .cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html