실행문맥에 대해 포스팅해보겠습니다.
실행문맥을 모르고도 코딩을 할 순 있지만, 실행문맥에 대해 알아야
클로저나 호이스팅, this의 원리같은 것들을 이해하기가 쉬운 것 같습니다.
실행문맥,실행컨텍스트,Execution Context 같습니다
실행문맥은 자바스크립트가 실행되는 문맥으로 추상적인 개념입니다.
문맥에 따라서 자바스크립트 엔진이 순서와 범위 등 코드를 실행하는데 필요한 정보를 파악합니다.
자바스크립트 엔진이 사람이 짜놓은 코드를 기계(js엔진) 입장에서 읽기 쉽도록 정리해놓은 것 정도로 생각됩니다.
하나의 실행문맥이 하나의 실행구역이기도 합니다.
1. 컨텍스트의 생성과 순서
프로그램 내의 코드들이 모두 하나의 컨텍스트로 정리되진 않습니다.
(컨텍스트는 둘 이상의 종류가 있고 , 종류마다 특정 조건에 생성됩니다.)
다음은 컨텍스트의 종류입니다.
- 전역 실행컨텍스트
- 함수 실행컨텍스트
- Eval 실행컨텍스트
이 중세 번째의 Eval컨텍스트는
MDN : Eval을 절대 사용하지 말 것을 읽어보시면 수 많은 취약점이 있어 사용하지 말 것을 권고합니다.
따라서, 사용하지 않을 것이니 Eval코드가 실행컨텍스트를 생성한다는 것 정도만 알면 되겠습니다.
가장 기본이 되는 실행컨텍스트입니다. 자바스크립트코드가 처음 실행되면 생성됩니다. 코드 전체의 정보를 가집니다.
함수가 호출되면 함수컨텍스트가 생성됩니다.
두 종류의 컨텍스트가 있습니다. 전역 컨텍스트는 자바스크립트 코드가 실행되면 생성되며 함수 컨텍스트는 함수가 호출되면 생성됩니다.
스택은 LIFO의 자료구조입니다. 네이버 지식백과 : STACK을 참고해주세요
가장 처음에 코드가 실행될 때 생성되는 전역컨텍스트가 스택에 쌓입니다.
그리고, 코드에서 함수호출을 만나면 함수컨텍스트가 생성되에 스택에 쌓입니다.
자바스크립트 엔진이 코드를 모두 읽고, 컨텍스트를 모두 생성해서 스택에 쌓고 나면! 쌓여있는 스택의 꼭대기부터 순서대로 실행시킵니다.
(책을 쌓고 가장 위에있는 책부터 읽는 것과 같습니다.)
2. 컨텍스트의 생성과정 , Detail
위 단락에서 컨텍스트를 개괄적으로 살펴봤다면, 이 번 단락에서는 컨텍스트 하나를 자세히 들여다보겠습니다.
실행문맥의 생성과정은 두 가지로 나뉩니다.
Creation stage, Execution stage라고도 불립니다.
하나씩 보겠습니다.
여기서 두 가지 일을 합니다.
인용 출처 , ES5,ES6 추상적인 구조
ExecutionContextES5 = {
ThisBinding: <this value>,
VariableEnvironment: { ... },
LexicalEnvironment: { ... },
}
ExecutionContextES6 = {
LexicalEnvironment = <ref. to LexicalEnvironment in memory>,
VariableEnvironment = <ref. to VariableEnvironment in memory>,
}
ES6 에서 LexicalEnvironment와 VariableEnvironment 둘의 차이점은 전자가 함수 선언과 변수 (let과 const)의 바인딩을 저장하고 후자는 변수 var 만 저장한다 라고 합니다. 첫 번째의 LexicalEnvironment에 대해서만 우선 자세히 알면 되겠습니다.
LexicalEnvironment는 세가지 일을 합니다.
Environment Records
Reference to the outer environment - outer lexical environment에 대한 접근을 의미합니다.
현재 컨텍스트에서 변수,함수 등을 찾지 못하면 상위 컨텍스트에서 해당 값에 접근한다는 의미입니다.
This binding - this의 값이 여기서 결정됩니다. 전역 컨텍스트에서는 기본으로 글로벌, 윈도우로 설정되어 있습니다.
함수컨텍스트에서는 object reference로 호출됐다면* this는 해당객체를 가리키게 되고,
object reference가 주어지지 않았다면*
global객체(브라우저에서는 window객체)를 가리키게 됩니다.
(엄격모드(strict mode)에서는 undefined를 가리킵니다.)
이 단계에서는 모든 변수에 대한 할당이 수행되고 코드가 최종적으로 실행됩니다!
해당 컨텍스트내의 인수목록(arguments),함수, 변수를 저장합니다. 값이 저장되지는 않으며 매핑됩니다.
사진에서의 두번째 코드를보면 foo의 값에 매핑됩니다.
Reference to the outer environment 현재 컨텍스트에 없다면 상위컨텍스트에서 매핑합니다.
조건에따라 this 바인딩 합니다.
// 1. object reference
const person = {
name: 'peter',
birthYear: 1994,
calcAge: function() {
console.log(2018 - this.birthYear);
}
}
person.calcAge();
// 2. no object reference
const calculateAge = person.calcAge;
calculateAge();
추상적인 형태를 보며 다시 한번 읽어보세요
*이 번 내용을 보며 더 궁금한 내용은 위에 있는 출처 링크를 따라가서 보시기 바랍니다.
*
개괄적으로라도 머리속에 정리해서
호이스팅, 클로저, 함수선언식과 표현식, this바인딩 등에 대한 이해를 돕기 위한 목적으로 포스팅했습니다. 무작정 외우면 이 것들은 더 하기싫때문에..(개인적인 생각)
읽어주셔서 감사합니다.
피드백이나 오역, 잘못이해한 부분등은 감사하게 받겠습니다.
let과 const의 경우는 블록단위로 스코프가 제한되는데 아래와 같은 상황에서 실행 컨텍스트의 Lexical Enviroment 구조가 궁금해지네요.
function Test() {
let a = 1;
{
let a = 3;
}
}