이 기사의 내용은 js 클로저와 그 기능에 대한 심층적인 이해를 공유하는 것입니다. 이는 특정 참조 가치가 있습니다. 도움이 필요한 친구가 참조할 수 있습니다.
이 코드에는 두 가지 특징이 있습니다.
1. b 함수 a 내부에 설정됨
2. 함수 a가 함수 b를 반환합니다.
참조 관계는 그림과 같습니다.
이렇게 하면 var c=a()를 실행한 후 변수 c가 실제로 b 함수를 가리키게 됩니다. i의 값을 표시합니다(첫 번째 시간은 1입니다). 이 코드는 실제로 클로저를 생성합니다. 이유는 무엇입니까? 함수 a 외부의 변수 c는 함수 a 내부의 함수 b를 참조하기 때문에 즉, 다음과 같습니다.
함수 a 내부의 함수 b가 함수 a 외부의 변수에 의해 참조되면 클로저가 생성됩니다.
더 철저하게 합시다. 소위 "클로저"는 생성자 본문에 있는 다른 함수를 대상 개체의 메서드 함수로 정의하고, 이 개체의 메서드 함수는 차례로 외부 함수 본문에 있는 임시 변수를 참조하는 것입니다. 이를 통해 대상 개체가 수명 동안 항상 메서드를 유지할 수 있는 한 원래 생성자 본문에서 사용된 임시 변수 값을 간접적으로 유지할 수 있습니다. 초기 생성자 호출이 종료되고 임시변수의 이름은 사라졌지만, 변수의 값은 항상 대상 객체의 메소드 내에서 참조할 수 있으며, 이 메소드를 통해서만 값에 접근할 수 있다. 동일한 생성자를 다시 호출하더라도 새 개체와 메서드만 생성되며 새 임시 변수는 마지막 호출과 독립적인 새 값에만 해당합니다.
간단히 말해서 클로저의 기능은 a가 실행되고 반환된 후 a의 내부 함수 b의 실행이 a 변수에 의존해야 하기 때문에 클로저가 Javascript의 가비지 수집 메커니즘 GC가 a가 차지한 리소스를 회수하는 것을 방지한다는 것입니다. . 이는 클로저의 역할에 대한 매우 간단한 설명입니다. 전문적이거나 엄격하지는 않지만 일반적인 의미는 클로저를 이해하는 데에는 단계별 프로세스가 필요하다는 것입니다.
위의 예에서 클로저의 존재로 인해 a의 i는 함수 a가 반환된 후에 항상 존재하게 됩니다. 이런 식으로 c()가 실행될 때마다 i는 1을 더한 후 경고되는 i 값이 됩니다.
그래서 a가 함수 b가 아닌 다른 것을 반환한다면 상황은 완전히 다릅니다. 왜냐하면 a가 실행된 후 b는 a의 외부 세계로 반환되지 않고 a에 의해서만 참조되기 때문입니다. 이때 a는 b에 의해서만 참조됩니다. 따라서 함수 a와 b는 서로를 참조하지만 방해받지 않습니다. 외부 세계에서 참조됨), 함수 a 및 b는 GC에 의해 재활용됩니다. (Javascript의 가비지 수집 메커니즘은 나중에 자세히 소개하겠습니다.)
클로저와 함수 a와 중첩 함수 b 사이의 관계를 더 깊이 이해하려면 함수 실행 컨텍스트(실행 컨텍스트), 활성 개체( 호출 개체), 범위, 범위 체인. 이러한 개념을 설명하기 위해 정의부터 실행까지 함수 a의 프로세스를 예로 들어 보겠습니다.
1. function a를 정의하면 js 인터프리터는 a를 정의할 때 a가 있는 "환경"으로 함수 a의 범위 체인을 설정합니다. a가 전역 함수인 경우 범위에는 창 개체만 있습니다. . 2. 함수 a를 실행하면 a는 해당 실행 컨텍스트로 들어갑니다. 3. 실행 환경을 생성하는 과정에서 먼저 a의 범위인 a에 범위 속성이 추가되며 해당 값은 1단계의 범위 체인입니다. 즉, a.scope=a의 범위 체인입니다. 4. 그러면 실행 환경이 호출 개체를 생성합니다. 활성 객체도 속성은 있지만 프로토타입이 없고 Javascript 코드를 통해 직접 액세스할 수 없는 객체입니다. 활성 개체를 만든 후 범위 체인의 맨 위에 활성 개체를 추가합니다. 이때 a의 범위 체인에는 a의 활성 개체와 창 개체라는 두 개체가 포함됩니다.
5. 다음 단계는 함수 a를 호출할 때 전달된 매개변수를 저장하는 활성 객체에 인수 속성을 추가하는 것입니다.
6. 마지막으로 함수 a의 모든 형식 매개변수와 내부 함수 b에 대한 참조를 a의 활성 개체에 추가합니다. 이번 단계에서는 함수 b의 정의가 완료되므로 3단계와 마찬가지로 함수 b의 스코프 체인은 b가 정의된 환경, 즉 a의 스코프에 설정된다.
이제 함수 정의부터 실행까지 전체 함수의 단계가 완료됩니다. 이때 a는 함수 b의 참조를 c에 반환하고 함수 b의 범위 체인에는 함수 a의 활성 개체에 대한 참조가 포함되어 있습니다. 이는 b가 a에 정의된 모든 변수와 함수에 액세스할 수 있음을 의미합니다. 함수 b는 c에 의해 참조되고 함수 b는 함수 a에 의존하므로 함수 a는 반환 후 GC에 의해 재활용되지 않습니다.
함수 b가 실행되면 위의 단계와 동일합니다. 따라서 실행 중 b의 범위 체인에는 다음 그림과 같이 b의 활성 개체, a의 활성 개체 및 창 개체의 3개 개체가 포함됩니다.
그림과 같이 함수 b에서 변수에 액세스할 때 이
1. 먼저 자신의 활성 객체를 검색하고, 존재하지 않으면 반환합니다. 함수 a의 활성 객체를 계속 검색하고, 존재할 때까지 순차적으로 검색합니다. 설립하다. 2. 함수 b에 프로토타입 프로토타입 객체가 있는 경우 먼저 자신의 활성 객체를 검색한 후 자신의 프로토타입 객체를 검색한 다음 계속 검색합니다. 이것은 Javascript의 변수 조회 메커니즘입니다.
3. 전체 범위 체인에서 찾을 수 없으면 정의되지 않은 값이 반환됩니다.
요약하면 이 단락에서는 함수의 정의와 실행이라는 두 가지 중요한 단어가 언급됩니다. 이 기사에서는 함수의 범위는 함수가 실행될 때가 아니라 함수가 정의될 때 결정된다고 언급합니다(1단계와 3단계 참조). 이 문제를 설명하려면 코드 조각을 사용하세요.
function f(x) { var g = function () { return x; } return g; } var h = f(1); alert(h());
첫 번째 가정이 true이면 출력 값은 정의되지 않으며, 두 번째 가정이 true이면 출력 값은 1입니다.
실행 결과는 두 번째 가정이 정확하다는 것을 증명하며, 함수가 정의될 때 함수의 범위가 실제로 결정된다는 것을 나타냅니다.
4. 클로저 적용 시나리오
함수 내 변수의 안전성을 보호하세요. 초기 예를 들어, 함수 a의 i는 함수 b를 통해서만 접근할 수 있고 다른 수단으로는 접근할 수 없으므로 i의 보안이 보호됩니다.
2. 변수의 보안을 보호하여 JS 프라이빗 속성과 프라이빗 메서드를 구현합니다. (외부에서 접근할 수 없습니다.)
프라이빗 속성과 메서드는 생성자 외부에서 접근할 수 없습니다.
function Constructor(...) { var that = this; var membername = value; function membername(...) {...} }
6. 결론
Javascript 클로저를 이해하는 것은 고급 JS 프로그래머가 되는 유일한 방법입니다. 그 해석과 작동 메커니즘을 이해해야만 더 안전하고 우아한 코드를 작성할 수 있습니다.
위 내용은 js 클로저와 그 기능에 대한 심층적인 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!