최근에, 나는 "JavaScript Advanced Programming 3"을 다시 읽고 있으며 배운 지식 중 일부를 기록하기 위해 블로그를 작성해야한다고 생각합니다. 그렇지 않으면 잊을 것입니다. 오늘 요약하고 싶은 것은 JS 실행 환경과 범위입니다.
먼저 실행 환경에 대해 이야기 해 봅시다
1. 실행 환경
이 책의 개념, 실행 환경은 변수 또는 함수가 액세스 할 수있는 다른 데이터를 정의하고 해당 행동을 결정합니다. 각 실행 환경에는 이와 관련된 가변 객체가 있습니다. 환경에 정의 된 모든 변수와 함수는이 객체에 저장됩니다. 코드를 작성할 때이 객체에 액세스 할 수는 없지만 파서는 데이터를 처리 할 때 백그라운드에서 사용합니다.
실행 환경은 변수 또는 함수가 다른 데이터에 액세스 할 수있는 권한이 있는지 여부를 정의하는 메커니즘입니다.
JavaScript에서 실행 가능한 JavaScript 코드는 세 가지 유형으로 나뉩니다.
1. 글로벌 코드, 즉 JS 파일, HTML 페이지에 포함 된 JS 코드 등과 같은 기능에없는 글로벌 코드 등
2. 평가 코드, 즉 Eval () 함수를 사용하여 동적으로 실행되는 JS 코드.
3. 기능 코드, 즉 사용자 정의 함수의 기능 본문 JS 코드.
평가 코드를 건너 뛰고 글로벌 실행 환경과 기능 실행 환경에 대해서만 이야기하십시오.
1. 글로벌 환경 :
글로벌 환경은 가장 주변 장치 실행 환경입니다. 글로벌 실행 환경은 창 객체로 간주됩니다. 따라서 모든 글로벌 변수 및 함수는 창 객체의 속성 및 방법으로 생성됩니다. 코드가 브라우저에로드되면 글로벌 실행 환경이 생성됩니다 (글로벌 실행 환경은 웹 페이지 나 브라우저를 닫을 때만 파괴됩니다). 예를 들어, 페이지에서 JS 코드가 처음로드 될 때 글로벌 실행 환경을 만듭니다.
이것이 또한 클로저가 메모리 누출 단점을 가진 이유이기도합니다. 폐쇄의 외부 기능은 지구 환경으로 취급되기 때문입니다. 따라서 파괴되지 않고 기억에 남을 것입니다.
2. 기능 실행 환경
각 기능에는 자체 실행 환경이 있습니다. 실행이 함수에 들어가면 함수의 실행 환경이 실행 환경 스택의 상단으로 밀려 들어가고 실행 권한을 얻습니다. 이 함수가 실행되면 실행 환경이 스택 상단에서 삭제되고 실행 권한이 이전 실행 환경으로 반환됩니다. 이것은 ECMAScript 프로그램의 실행 흐름입니다.
이러한 방식으로 해석 될 수 있습니다. JavaScript 함수가 호출되면 함수가 함수에 해당하는 실행 환경에 들어갑니다. 다른 함수가 호출되면 새로운 실행 환경이 생성되고 기능 호출 중에 실행 프로세스가 해당 환경에 있습니다. 호출 된 함수가 반환되면 실행 프로세스는 원래 실행 환경으로 돌아갑니다. 따라서 JavaScript 코드를 실행하면 실행 환경 스택이 형성됩니다.
함수가 호출되면 함수의 로컬 환경이 생성됩니다 (함수의 코드가 실행 된 후에는 환경이 파괴되고 저장된 모든 변수 및 기능 정의도 파괴됩니다).
2-1 정의 기간
함수가 정의되면 [[scope]] 속성이 생성됩니다. 이 개체는 객체 목록에 해당합니다. 목록의 객체는 JavaScript에서만 내부적으로 액세스 할 수 있으며 구문을 통해 액세스 할 수 없습니다.
(범위는 범위를 의미합니다.)
글로벌 함수 a를 정의 한 다음 A 함수는 a의 [[scope]] 속성을 만듭니다. 현재 [[scope]]에는 전역 객체 [Global Object] 만 포함됩니다.
A 내부에서 함수 B를 정의하면 함수 B도 [[scope]] 속성을 생성합니다. B의 [[scope]] 속성에는 두 개의 객체가 포함되어 있으며, 하나는 활성 객체 A의 활성 객체 활성화 객체이고 다른 하나는 전역 객체입니다. A의 활성 객체가 앞쪽에 있고 전역 객체는 뒷면에 있습니다.
요컨대, 함수의 [스코프] 속성에서 객체 목록의 순서는 이전 함수 레이어의 활성화 객체 객체와 상단 층이 가장 바깥 쪽 글로벌 객체까지입니다.
샘플 코드는 다음과 같습니다. A는 하나의 범위 만 가지고 있으며 B에는 두 개의 스코프가 있습니다.
// 외부 함수 함수 a () {var somevar; // 내부 함수 함수 b () {var somevar; }}2-2 실행 기간
함수가 실행되면 함수의 실행 환경에 들어갑니다. 첫째, 자체 활성 객체 [활성화 객체] (이 개체는 이것, 인수, 로컬 변수 (이름 지정된 매개 변수 포함) 및 가변 객체의 스코프 체인의 정의를 포함합니다. 그런 다음 실행 환경의 범위를 [[스코프 체인]] 순서대로 복사하고 [스코프 체인]의 상단에 [Scope Chain]의 상단으로 밀려납니다. 및 실행 환경에 액세스 할 수있는 권한이있는 개체.
// 첫 번째 단계는 글로벌 실행 환경을 만드는 것입니다. 글로벌 실행 컨텍스트 및 글로벌 활동 개체. // 창 객체 만 포함하는 글로벌 [[scope]]를 정의합니다. // 전역 정의 변수와 함수 객체를 스캔합니다. 색상 【【【【【【【【fd는 창에 추가 된 changecolor [[scope]]를 생성하므로 글로벌 변수와 글로벌 함수 객체는 윈도우의 특성으로 정의됩니다. // 프로그램이 정의 되었으므로이 실행 환경의 어느 곳에서나 changecolor ()를 실행할 수 있습니다. 색상이 정의되었지만 값은 정의되지 않았지만 // 두 번째 단계는 "blue"var color = "blue"를 할당하는 색상입니다. // 할당이 필요하지 않으며, 그 자체의 함수 changecolor () {// 네 번째 단계는 changecolor [[scope]]의 실행 환경으로 유효한 대상을 복사하고, funcibe에 정의하고, 정의 된 변형으로 스캔합니다. 또 다른 콜러 【【【】 및 swapcolors 【fd는 swapcolors [[scope]]를 생성하고 활성 객체와 글로벌 활성 객체를 활성 객체에 추가하고 인수를 추가하고 인수를 추가 하고이 객체가 스코프 체인 상단으로 정의되어 () 가이 실행 환경에서 실행 될 수 있습니다. 또 다른 콜러가 정의되었지만 그 값은 정의되지 않았습니다. // 할당이 필요하지 않으며, 자체 기능 SwapColors () {// 7 단계 SwapColors의 실행 환경을 입력하고 SwapColors '[[Scope]]를 카피로 작성하여 변수를 정의하고 기능 객체를 정의하기 위해 스캔하여 변수를 정의하여 SCOLORBLES를 추가하여 this // this // this // this // this // 다른 콜러의 템플러 할당 값, 또 다른 콜러 및 색상은 스코프 체인을 따라 찾을 수 있으며 var tempcolor = 다른 콜로를 계속 실행합니다. 다른 콜러 = 색상; color = tempcolor; } // 6 단계 : SwapColors를 실행하고 실행 환경을 입력하십시오 SwapColors ();} // 3 단계 : ChangeColor를 실행하고 실행 환경을 입력하십시오. ChangeColor ();2-3 액세스 식별자 :
JS 코드 실행 중에 식별자가 발생하면 식별자의 이름을 기반으로 실행 컨텍스트 (실행 컨텍스트)의 스코프 체인에서 검색됩니다. 스코프 체인의 첫 번째 객체 (함수의 활성화 객체 객체)에서 시작하여 찾을 수없는 경우 스코프 체인에서 다음 객체를 검색하고 식별자 정의가 발견 될 때까지 반복하십시오. 검색을 검색 한 후 범위의 마지막 객체를 찾을 수없는 경우, 즉 글로벌 오브젝트 (글로벌 개체)가 오류가 발생하여 정의되지 않았습니다.
2. 스코프/스코프 체인 (스코프/스코프 체인)
코드가 환경에서 실행되면 스코프 체인이 생성됩니다. 범위 체인의 목적은 실행 환경에 액세스 할 수있는 권한이있는 모든 변수 및 기능에 순서대로 액세스 할 수 있도록하는 것입니다. 전체 스코프 체인은 규칙에 따라 다른 실행 위치에서 가변 객체에 의해 구성된 링크 된 목록입니다. 스코프 체인의 프론트 엔드는 항상 실행중인 코드가 위치한 환경의 가변 객체입니다.
이 환경이 함수 인 경우 활성화 객체는 가변 객체로 사용됩니다. 활성 객체는 처음에 하나의 변수 만 포함하며, 이는 함수 내부의 인수 객체입니다. 범위 체인의 다음 변수 객체는 기능의 포함 환경에서 나오고 다음 변수 객체는 다음 포함 환경에서 나옵니다. 이러한 방식으로 글로벌 실행 환경으로 계속되며 글로벌 실행 환경의 가변 객체는 항상 범위 체인의 마지막 객체입니다.
그림과 같이 :
책의 예 :
var color = "blue"; 함수 changecolor () {var exercolor = "red"; 함수 swapcolors () {var tempcolor = 다른 콜러; 다른 콜러 = 색상; color = tempcolor; // todo something} swapcolors ();} changecolor (); // 여기에서 템플러와 아코 콜러에 액세스 할 수 없습니다. 그러나 색상에 액세스 할 수 있습니다. 경고 ( "색상은 이제"+색상);위의 분석을 통해 내부 환경이 스코프 체인을 통해 모든 외부 환경에 액세스 할 수 있지만 외부 환경은 내부 환경의 변수와 기능에 액세스 할 수 없다는 것을 알 수 있습니다.
이러한 환경은 선형적이고 순서입니다. 각 환경은 쿼리 변수 및 기능 이름까지 범위 체인을 위로 검색 할 수 있습니다. 그러나 모든 환경은 스코프 체인을 아래쪽으로 검색하여 다른 실행 환경에 들어갈 수 없습니다.
위의 예에서 swapcolor () 함수의 경우, 스코프 체인에는 swapcolor () variable 객체, changecolor () 변수 객체 및 글로벌 객체가 포함됩니다. SwapColor ()의 로컬 환경은 자체 변수 객체에서 변수 및 함수 이름을 검색하기 시작합니다. 찾을 수없는 경우 ChangeColor 범위 체인을 위쪽으로 검색하십시오. . . . . 등. 그러나 changecolor () 함수는 swapcolor의 변수에 액세스 할 수 없습니다
요한 계시록 : 검색 시간을 줄이기 위해 로컬 변수를 사용하십시오.
1. 블록 레벨 범위가 없습니다
C, C ++ 및 Java와 달리 JavaScript에는 블록 레벨 범위가 없습니다. 다음 코드를보십시오.
if (true) {var myvar = "Zhang San"; } alert (myvar); // Zhang San블록 수준의 범위가있는 경우 MyVar는 외부에서 액세스 할 수 없습니다. 다음을보십시오
for (var i = 0; i <10; i ++) {console.log (i)} alert (i); // 10Java 또는 C# 코드와 같은 블록 수준 범위가있는 언어의 경우 초기화 된 변수이며 외부에 액세스 할 수 없습니다. for 루프 중량에만 존재하기 때문에 For 루프를 실행 한 후에는 FOR의 모든 변수가 파괴됩니다. JavaScript에서는 그렇지 않습니다. FOR의 변수 선언은 현재 실행 환경에 추가됩니다 (여기에는 글로벌 실행 환경이 있습니다). 따라서 FOR 루프가 완료된 후에는 루프 외부의 실행 환경에 여전히 존재하는 변수가 존재합니다. 따라서 10은 출력됩니다.
2. 변수를 선언합니다
VAR을 사용하여 변수가 선언되면이 변수는 가장 가까운 사용 가능한 환경에 자동으로 추가됩니다. 함수 내부의 경우 가장 가까운 환경은 함수의 로컬 변수입니다. 변수가 초기화되지 않으면 변수가 전체 기능에 자동으로 추가됩니다.
코드는 다음과 같습니다.
var name = "Xiao Ming"; 함수 getName () {alert (name); // '정의되지 않은'var name = 'Xiao Huang'; 경고 (이름); // Xiao Huang} getName ()이름이 정의되지 않은 이유는 무엇입니까? JavaScript Parser는 기능 실행 환경에 들어가서 Var 및 기능을 먼저 스캔하기 때문입니다.
VAR 또는 함수 [함수 선언] 선언을 실행 환경의 최상위로 홍보하는 것과 같습니다.
다시 말해, getName 함수를 입력 할 때 식별자 검색 메커니즘은 VAR을 찾고 이름은 전역 이름이 아닌 로컬 변수 이름입니다. 함수의 이름이 상단으로 홍보되기 때문입니다.
위의 코드는 다음과 같이 구문 분석됩니다.
var name = "Xiao Ming"; 함수 getName () {var name; 경고 (이름); // '정의되지 않은'var name = 'Xiao Huang'; 경고 (이름); // Xiao Huang} getName ()스코프 체인 확장 :
실행 환경에는 두 가지 유형의 실행 환경이 있지만 글로벌 범위와 기능적 범위가 있지만 스코프 체인은 여전히 어떤 식 으로든 확장 될 수 있습니다. 일부 명령문은 스코프 체인의 상단에 임시 변수 객체를 추가 할 수 있기 때문입니다.
이런 일이 발생하는 두 가지 상황이 있습니다.
1. Try-Catch 문의 캐치 블록;
2. 진술과 함께;
위는이 기사에 관한 것입니다. 모든 사람이 JavaScript 실행 환경과 범위를 배우고 이해하는 것이 도움이되기를 바랍니다.