-
Execution ContextJS 2021. 8. 7. 17:00
Context란?
어떤 코드에 관여하는 코드 맥락상의 조건, 환경
그럼 실행 콘텍스트 Execution Context란?
동일한 조건,환경을 지니는 코드뭉치를/ 실행할 때 필요한 조건,환경정보
여기서 말하는 동일한 환경을 지니는 코드뭉치는 함수 또는 전역공간 뿐.
=> 함수를 실행할 때 필요한 환경정보 !
Variable Environment - 값 변경 불가(snapshot)
Lexical Environment - 값 변경 가능
[ Lexical Enviroment ]
- environmentRecord (현재 컨텍스트의 식별자)
: 현재 문맥의 식별자 정보를 수집해서 끌어올림 => Hoisting과 같음
-outerEnvironmentReference (외부 컨텍스트의 식별자)
: 현재 문맥에 관련있는 외부 식별자 정보를 담는다
Execution Context가 실행되면,
가장 먼저 environmentRecord로 현재 문맥의 식별자 정보를 수집해서 끌어올린다는 것을 기억하자!
( * 단, 할당된 값까지 끌어올리지는 않음)
var a = 1; function outer() { console.log(a); // 1 function inner() { console.log(a); // 2 var a = 3; } inner();//inner를 만났을때 그제야 inner의 실행 콘텍스트가 열리며 console.log(a); // 3 // inner 실행이 끝났으니까 이걸 실행 } outer(); //outer를 만났을때 그제야 outer의 실행 콘텍스트가 열리며 console.log(a); // 4 // outer 실행이 끝났으니까 이걸 실행 // 이렇게 마지막에 들어온게 가장먼저 빠지는 구조를 stack이라고 한다 // 실행에 대한 것을 관여하는 것을 call stack이라고 함 /* 현재 어떤 함수가 동작하고 있는지, 다음에 어떤 함수가 호출되어야 하는지 등을 제어하는 자료구조 */
Call Stack 설명 inner LexicalEnvironment environmentRecord (내부접근가능) outerEnvironmentReference(외부접근가능) - outer에 접근가능 outer LexicalEnvironment environmentRecord (내부접근가능) outerEnvironmentReference(외부접근가능) - 전역에 접근가능 전역 LexicalEnvironment environmentRecord (내부접근가능) * 내부로는 접근할 수 없다. 접근가능한 방법이 없음. 참조하고 있는 대상X
ex) inner에서 선언한 var a = 1; 을 outer나 전역에서는 불러올 수 없음.
하지만 전역에서 선언한 var a = 1;은 outer나 inner에서 불러올 수 있다.(outer나 inner에서 a를 선언해버리지 않은 이상)
- 그런데 만약
전역으로 var a = 1; outer에서 var a = 2; 로 선언되어있는 상태에서
inner에서 var a의 값을 불러오려고 하면 뭐가 출력될까?
=> outer에서 할당한 a = 2가 출력된다. 제일 가까운 것을 찾기 때문에!
전역의 a값과 outer의 a값 둘 다 있지만, outer에서 a를 선언함으로써 전역으로의 a 접근을 막는다
이 도표를 바탕으로 위의 코드블럭을 실행 순서대로 자세히 설명하면
var a = 1; function outer() { // outer가 실행되면 제일 먼저 내부의 선언된 식별자를 찾아 끌어올림 // 그래서 inner가 먼저 선언된 셈. console.log(a); // outer엔 a가 없으니 전역에서 a를 찾아서 1을 출력 function inner(){ //inner가 실행됐으니 변수 a를 수집해 올려서 선언 console.log(a); // 이미 선언되어있기 때문에 inner내부에서 a를 찾는다. //하지만 선언만 됐을 뿐, 값은 아직 할당되지 않았음! undefined 출력!!!! var a = 3; // 그러고 나서야 a에 3이라는 값을 할당한다 } inner(); // inner를 실행(execution 컨텍스트 활성화) // inner함수는 종료됨 console.log(a); //inner에는 접근할 수 없음. outer에서 a를 찾는다 // a가 없으니 전역으로 1을 출력한다 } outer(); //outer 실행 // 함수 outer종료 console.log(a); // 전역으로 나가서 찾아온 1을 출력한다
function inner(){ //inner가 실행됐으니 변수 a를 수집해 올려서 선언
console.log(a); // 이미 선언되어있기 때문에 inner내부에서 a를 찾는다.
//하지만 선언만 됐을 뿐, 값은 아직 할당되지 않았음! undefined 출력!!!!
var a = 3;
// 그러고 나서야 a에 3이라는 값을 할당한다
}
* 이부분을 주의하자.
위로 끌어올리는 environment Record(=Hoisting)은 단순히 선언만 위에서 할 뿐, 할당은 아직 되지 않았다는 것을 잘 기억하자.
선언은 되어있지만 값이 할당되어있지 않으니 undefined라고 나올 수 밖에.