먼저, 다음은 범위를 설명하는 세 가지 코드입니다.
// ============ 예제 1 ============= var scope = 'global'; function fn () {alert (scope); var scope = 'local'; 경고 (스코프);} fn (); // 출력 결과? 경고 (범위); // 출력 결과? // ============ 예제 2 ============ var scope = 'global'; function fn () {alert (scope); 범위 = '로컬'; 경고 (스코프);} fn (); // 출력 결과? 경고 (범위); // 출력 결과? // ============ 예제 3 =========== Var Scope = 'Global'; function fn (scope) {alert (scope); 범위 = '로컬'; 경고 (스코프);} fn (); // 출력 결과? 경고 (범위); // 출력 결과?이 세 코드는 작은 차이 만 있지만 결과는 완전히 다릅니다. 예 1 출력 [undefined, local, global], 예제 2 출력 [글로벌, 로컬, 로컬], 예 3 출력 [미정, 로컬, 글로벌]. 올바르게 대답 할 수 없다면, 아직 JavaScript의 범위 특성을 이해하지 못했음을 의미합니다.
스코프 란 무엇입니까?
누군가가 물어볼 수 있습니다 : 변수 a의 범위는 무엇입니까? 나는 나중에 다시 물었다 : 기능의 범위는 무엇입니까? 변수와 함수의 범위는 무엇입니까?
먼저 "스코프"의 의미를 살펴 보겠습니다. "스코프"가 분해되면 "기능"과 "도메인"을 의미합니다.
범위는 접근 가능한 변수 및 함수 범위 또는 변수 또는 함수가 작동하는 영역입니다.
1. JavaScript 기능의 스코프 :
함수 내 영역은 함수의 범위이며 변수와 함수 모두이 영역에서 작업에 액세스 할 수 있습니다. 가장 바깥 함수 외부의 영역을 글로벌 범위라고하며 함수 내부의 영역을 로컬 범위라고합니다.
2. JavaScript 변수의 범위 :
변수가 소스 코드에있는 영역에서는이 변수의 범위가 있으며이 영역 내에서 변수에 액세스하고 작동 할 수 있습니다. 글로벌 범위에 정의 된 변수는 글로벌 변수라고하며 함수에 정의 된 변수를 로컬 변수라고합니다.
간단히 말해서, JS 소스 코드는 함수 {}별로 블록 영역으로 나뉩니다. 이러한 영역이 정체성을 바꾸면 특정 함수 또는 특정 변수의 범위입니다. 변수의 범위와 함수의 범위는 소스 코드의 동일한 영역을 참조 할 수 있습니다.
스코프 체인
스코프 체인은 JavaScript 내의 변수 및 기능 검색 메커니즘입니다. 변수와 함수, 즉 범위의 범위를 결정합니다. 스코프 체인의 원리를 이해하면 이전 기사의 세 가지 예를 이해하여 이유와 이유를 알 수 있습니다.
스코프 체인은 ECMAScript-262 문서의 개념입니다. JavaScript 엔진은 ECMAScript-262 문서에 따라 구현됩니다. JavaScript 엔진의 작동 원리를 이해하는 것은 JavaScript의 특성에 대한 우리의 이해에 도움이되지만 대부분의 JS 프로그래머는 매우 근본적인 기술을 이해하지 못할 것입니다. 따라서 ECMAScript-262 문서를 읽을 때 JavaScript 엔진의 작동 원리를 시뮬레이션하는 직관적 인 방법을 가질 수 있습니다.
이 기사는 1999 년 ECMAScript-262-3의 세 번째 판을 통해 범위 체인을 형성하는 원칙을 설명 할 것이며, 실행 환경, 가변 객체 및 활성 객체, 인수 개체, 범위 체인 등과 같은 몇 가지 개념을 소개 할 것입니다. 차이점은 가변 객체 및 활성 객체와 같은 개념이 취소되었으며 어휘 환경 및 환경 기록과 같은 새로운 개념이 도입되므로 두 버전의 개념을 혼동하지 마십시오.
1. 실행 컨텍스트
실행 컨텍스트도 실행 컨텍스트로 변환됩니다. 구문 분석기가 ECMAScript의 실행 코드에 들어가면 파서는 실행 환경에 들어갑니다. 활성 실행 환경은 논리적 스택을 형성합니다. 이 논리적 스택의 맨 위에있는 실행 환경은 현재 실행 실행 환경입니다.
참고 : ECMAScript, 글로벌, 기능 및 평가에는 세 가지 유형의 실행 코드가 있습니다. 글로벌 환경은 글로벌 실행 코드이며 함수는 기능 실행 코드입니다. 로직 스택은 특수 데이터 스토리지 형식으로 '첫 번째 및 아웃 및 아웃 및 아웃'으로 특징 지어집니다. 데이터 추가는 먼저 로직 스택의 상단으로 푸시되며 데이터 삭제는 상단에서 삭제되어야합니다.
가변 객체, 활성 객체 및 인수 객체
각 실행 환경에는 이와 관련된 가변 객체가 있습니다. 파서가 실행 환경에 들어가면 가변 객체가 생성되며, 이는 현재 실행 환경에서 선언 된 변수 및 기능에 대한 참조를 보유합니다.
가변 객체는 추상 개념입니다. 다른 실행 환경에서는 가변 객체마다 식별이 다릅니다. 파서가 실행 환경에 들어가기 전에 전역 객체가 생성됩니다. 파서가 글로벌 실행 환경에 들어가면 글로벌 객체는 가변 객체 역할을합니다. 파서가 함수로 들어가면 활성 객체가 변수 객체로 생성됩니다.
2. 파서가 코드를 처리 할 때 두 단계
우리는 모두 JavaScript Parser가 코드를 하나씩 구문 분석한다는 것을 알고 있습니다. 매트입니까? 여기에는 파서가 코드를 처리하고 코드를 구문 분석하고 코드를 실행할 때 두 단계가 포함됩니다.
파서가 실행 환경에 들어가면 변수 객체는 실행 환경에서 선언 된 변수와 함수를 속성으로 추가하므로 변수와 함수는 선언 전에 사용할 수 있고 변수 값이 정의되지 않음을 의미합니다. 이것이 변수 및 함수 선언 (호이 스팅)의 촉진 이유입니다. 동시에, 스코프 체인과 이것은 결정됩니다. 이 프로세스는 일반적으로 사전 준비로 알려진 구문 분석 단계입니다. 그런 다음 파서는 코드를 실행하기 시작하고 변수에 해당 값에 대한 참조를 추가하고 실행 결과를 얻습니다. 이 프로세스는 실행 단계입니다.
두 가지 맛있는 밤을 말해 봅시다.
var a = 123; var b = "abc"; function c () {alert ('11 ');}위의 글로벌 환경에서 코드 구문 분석 및 실행 후 글로벌 객체는 가변 객체로 사용되며 다음 데이터가 저장됩니다.
함수 testfn (a) {var b = "123"; 함수 c () {alert ( "abc"); }} testfn (10);파서가 함수 실행 환경에 들어가면 활성 객체가 변수 객체로 생성됩니다. 활성 객체는 또한 인수 객체를 만듭니다. 인수 객체는 매개 변수를 저장하기위한 매개 변수입니다. 이것이 우리가 기능을 작성할 때 인수 [0]를 사용할 수있는 이유입니다.
3. 스코프 체인
각 실행 환경에는 이와 관련된 스코프 체인이 있습니다. 파서가 실행 환경에 들어가면 정의됩니다. 스코프 체인은 각 변수 객체에서 변수와 함수를 검색하는 데 사용되는 객체 목록입니다. 이를 통해 실행 환경에 어떤 변수 및 함수에 액세스 할 권리가 있는지 확인합니다. 예를 들어, 그것은 밤나무입니다.
var a = '123'; 함수 testfn (b) {var c = 'abc'; 함수 testfn2 () {var d = 'efg'; 경고 (a); } testfn2 ();} testfn (10);변수 a는 testfn2에서 선언되지 않습니다. TestFN2가 글로벌 변수 A를 호출 할 수있는 이유는 무엇입니까? 전체 프로세스는 어떻게 이루어 졌습니까? 아래 그림을 참조하십시오.
파서가 글로벌 실행 환경에 들어가면 변수와 기능은 호출 할 때 글로벌 객체에서만 발견됩니다.
파서가 testfn 함수 실행 환경에 들어가면, 함수 [[scope]]의 내부 속성이 먼저 글로벌 오브젝트로 채워지고 TestFN 활성 객체가 글로벌 오브젝트에 추가되어 스코프 체인을 형성합니다.
파서가 testfn2 함수 실행 환경에 들어가면, 함수 [[scope]]의 내부 속성이 먼저 상위 스코프 체인에 채워지고 현재 testfn2 활성 오브젝트가 스코프 체인의 프론트 엔드에 추가되어 새로운 스코프 체인을 형성합니다.
testfn2가 변수 a를 호출 할 때, 현재 testfn2 활성 객체에서 먼저 검색하십시오. 찾을 수없는 경우 스코프 체인을 위쪽으로 따르십시오. 발견되지 않으면 스코프 체인을 찾으십시오. 발견되지 않으면 마지막 글로벌 객체에서 발견 될 때까지 스코프 체인을 찾아보십시오. 그렇지 않으면 오류 가보고됩니다. 따라서 외부 환경의 변수는 함수 내부에서 호출 될 수 있으며 외부 환경의 변수를 함수 내부에서 호출 할 수 없습니다. 이것이 범위 특성의 원리입니다.