var foo = "hello"; var c = (함수 a () {함수 b () {var bar = "world"; alert (foo + bar); return bar;} return b;}) () (); Alert (foo + c);이 예제는 Hello World를 두 번 나타냅니다.
1. 폐쇄 란 무엇입니까?
"공식"설명은 다음과 같습니다. 소위 "클로저"는 많은 변수와 이러한 변수에 제한된 환경이있는 표현식 (일반적으로 함수)을 나타냅니다. 따라서 이러한 변수는 표현식의 일부입니다.
나는이 문장을 너무 학문적으로 묘사했기 때문에이 문장을 직접 이해할 수있는 사람은 거의 없다고 생각합니다. 나는 폐쇄 생성 과정을 건너 뛰면 폐쇄의 정의를 직접 이해하는 것이 매우 어렵 기 때문에 JavaScript에서 폐쇄를 만드는 방법을 사용하고 싶습니다. 다음 코드를보십시오.
함수 a () {var i = 0; 함수 b () {alert (++ i);} return b;} var c = a (); c ();이 코드에는 두 가지 특성이 있습니다.
1. 함수 B는 내부 기능 A;
2. 함수 a 반환 함수 b.
이러한 방식으로, var c = a ()를 실행 한 후 변수 c는 실제로 b를 가리 킵니다. c ()를 실행 한 후에는 창이 팝업되어 i의 값을 표시합니다 (처음은 1). 이 코드는 실제로 폐쇄를 만듭니다. 왜? 변수 C 외부 기능 A는 내부 함수 A, 즉, 즉 :
함수 A의 내부 함수 B가 변수 외부 함수 A에 의해 참조되면 폐쇄가 생성됩니다.
폐쇄가 무엇인지 모르기 때문에 여전히 폐쇄를 이해하지 못하는 것 같습니다. 아래에서 계속 탐색합시다.
2. 폐쇄의 기능은 무엇입니까?
요컨대, 폐쇄의 기능은 A가 실행되고 반환 된 후, 폐쇄는 JavaScript 쓰레기 수집 메커니즘 GC가 A가 차지하는 자원을 복구하지 않는다는 것입니다. A의 변수에 의존해야하기 때문입니다. 이것은 전문적이거나 엄격하지는 않지만 폐쇄의 역할에 대한 매우 간단한 설명이지만 대략적으로 의미합니다. 폐쇄를 이해하려면 점진적인 프로세스가 필요합니다.
위의 예에서, 함수 a가 반환 된 후에, 나는 A가 항상 존재하므로 c ()가 실행 될 때마다 1을 추가 한 후에 경고 한 값이다.
그런 다음 또 다른 상황을 상상해 봅시다. A가 작동하지 않으면 B가 B가 작동하지 않으면 상황이 완전히 다릅니다. A가 실행 된 후 B가 A의 외부 세계로 반환되지는 않지만 A에 의해서만 참조되므로 현재 A는 B에 의해서만 참조되므로 기능 A와 B는 서로 참조되지만 외부 세계에 의해 방해받지 않지만 (외부 세계에서 언급) 기능 A와 B는 GC에 의해 재활용됩니다. (JavaScript의 쓰레기 수집 메커니즘은 나중에 자세히 소개됩니다)
3. 폐쇄의 현미경 세계
클로저와 기능 A와 중첩 함수 B의 관계를 더 깊이 이해하려면 기능의 실행 환경 (Excution Context), 활성 객체 (호출 객체), 스코프 (범위) 및 범위 체인 등 여러 가지 다른 개념을 소개해야합니다. 이러한 개념을 설명하기 위해 기능 A 과정을 정의에서 실행으로 가져옵니다.
1. 함수 A를 정의 할 때 JS 통역사는 기능 A의 범위 체인을 "환경"으로 설정합니다. 여기서 A는 A가 a를 정의 할 때 위치합니다. A가 글로벌 함수 인 경우 스코프 체인에는 창 객체 만 있습니다.
2. 기능 A가 실행되면 A는 해당 실행 환경 (Excution Context)에 들어갑니다.
3. 실행 환경을 생성하는 과정에서 A는 먼저 범위 속성, 즉 A의 범위를 추가하고 값은 1 단계의 범위 체인입니다. 즉, A.Scope = a의 범위 체인입니다.
4. 실행 환경은 활성 객체 (호출 객체)를 만듭니다. 활성 객체는 속성이있는 객체이지만 프로토 타입이 없으며 JavaScript 코드를 통해 직접 액세스 할 수 없습니다. 활성 객체를 만든 후 활성 객체를 a의 스코프 체인의 상단에 추가하십시오. 현재 A의 스코프 체인에는 두 개의 객체 인 A의 활성 객체와 창 객체가 포함됩니다.
5. 다음 단계는 활성 객체에 인수 속성을 추가하는 것입니다.이 객체는 함수 a를 호출 할 때 전달되는 매개 변수를 저장합니다.
6. 마지막으로 함수 A의 모든 공식 매개 변수와 내부 함수 B에 대한 참조를 A의 활성 객체에 추가하십시오. 이 단계에서는 기능 B의 정의가 완료되므로 단계 3에서와 같이 함수 B의 범위 체인은 B로 정의 된 환경, 즉 A의 범위로 설정됩니다.
이 시점에서 전체 기능 A는 정의에서 실행으로 완료됩니다. 이때 A는 함수 B에 대한 참조를 반환하고 함수 B의 범위 체인은 함수 A의 활성 객체에 대한 참조, 즉 B는 A에 정의 된 모든 변수 및 함수에 액세스 할 수 있습니다. 함수 B는 C에 의해 참조되고 함수 B는 함수 A에 의존하므로 기능 A는 반환 후 GC에 의해 재활용되지 않습니다.
함수 B가 실행되면 위와 동일합니다. 따라서 실행 중 B의 스코프 체인에는 3 개의 객체가 포함됩니다 : 아래 그림과 같이 B의 활성 객체, A의 활성 객체 및 창 객체는 다음과 같습니다.
그림에서 볼 수 있듯이 함수 B의 변수에 액세스 할 때 검색 순서는 먼저 자체 활성 객체를 검색하는 것이며, 존재하는 경우 리턴됩니다. 존재하지 않으면 함수 A의 활성 객체를 계속 검색하고 발견 될 때까지 검색합니다. 전체 스코프 체인에서 찾을 수없는 경우 정의되지 않은 것이 반환됩니다. 기능 B에 대한 프로토 타입 프로토 타입 객체가있는 경우 자체 활성 객체를 검색 한 후 먼저 자체 프로토 타입 객체를 찾은 다음 계속 검색하십시오. 이것은 JavaScript의 변수 검색 메커니즘입니다.
4. 폐쇄의 응용 시나리오
1. 함수에서 변수의 보안을 보호하십시오. 첫 번째 예제를 예제로, 함수 A의 예를 들어, 함수 B로만 액세스 할 수 있지만 다른 채널을 통해서는 액세스 할 수 없으므로 i의 보안을 보호합니다.
2. 메모리 변수를 유지하십시오. 여전히 폐쇄로 인해, 나는 기능적으로 A가 항상 메모리에 존재하므로 c ()가 실행 될 때마다 추가됩니다.
위의 두 가지 점은 클로저를위한 가장 기본적인 응용 프로그램 시나리오이며, 많은 고전적인 경우가 시작됩니다.
5. JavaScript의 쓰레기 수집 메커니즘
JavaScript에서 객체를 더 이상 참조하지 않으면 GC에 의해 개체를 재활용합니다. 두 객체가 서로 참조되고 더 이상 세 번째 사람이 참조하지 않으면 서로 참조 된 두 개체가 재활용됩니다. 함수 A는 B로 참조되므로 B는 C로 C에 의해 참조되므로 실행 후에 기능 A가 재활용되지 않는 이유입니다.
위의 기사는 폐쇄 메커니즘이 내가 당신과 공유하는 모든 내용이라는 것을 종합적으로 이해합니다. 나는 당신이 당신에게 참조를 줄 수 있기를 바랍니다. 그리고 당신이 wulin.com을 더 지원할 수 있기를 바랍니다.