const a = 1;
const b = 2;
function add(n) {
const a = 11;
const b = 22;
console.log(n+a+b); // 66
}
add(33);
console.log(a+b) // 3
의 실행과정을 살펴보면
a,b
) -> 함수 호출(add(33)
)n+a+b
실행이처럼 코드 실행을 위해 필요한 것들은 다음과 같다.
이러한 것들을 관리하는 것이 실행 컨텍스트이다.
Stack 자료구조를 이용하여 코드 실행 순서를 관리한다.
전역 -> foo()
-> bar()
을 호출했다고 치면
1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|
bar 함수 실행 컨텍스트 | ||||||
foo 함수 실행 컨텍스트 | foo 함수 실행 컨텍스트 | foo 함수 실행 컨텍스트 | ||||
전역 실행 컨텍스트 | 전역 실행 컨텍스트 | 전역 실행 컨텍스트 | 전역 실행 컨텍스트 | 전역 실행 컨텍스트 |
전역 -> foo() -> bar()
전역 객체 생성
전역 코드 평가
var 전역 변수 | 전역 함수 | let const 전역 변수 | |
---|---|---|---|
평가 단계 | key로 등록 -> undefined 로 초기화 | key로 등록 -> 함수 객체를 생성하여 할당 | key로 등록 |
실행 단계 | 값을 등록 | 초기화 |
foo함수 코드 평가
bar함수 코드 평가
console.log
는 스코프체인 bar -> foo -> 전역에 따라 검색한다.bar 함수 코드 실행 종료
foo 함수 코드 실행 종료
전역 코드 실행 종료
JS 엔진이란 뭘까? 가 궁금해서 찾아본 글 (https://oowgnoj.dev/review/advanced-js-1)
실행 컨텍스트 부분은 단어가 굉장히 난해하고 구조도 복잡하다. 하지만 결론만큼은 간단하다고 생각한다.
function ExecutionContext(environmentRecord, outer) {
this.environmentRecord = environmentRecord;
this.outer = outer;
this.findProperty = function findProperty(property) {
const foundValue = this.environmentRecord[property];
if (!foundValue && !this.outer) return null;
return foundValue ? foundValue : this.outer.findProperty(property);
};
}
const globalExecutionContext = new ExecutionContext({ x: 1 }, null);
const fooExecutionContext = new ExecutionContext(
{ y: 2 },
globalExecutionContext
);
const barExecutionContext = new ExecutionContext(
{ z: 3 },
fooExecutionContext
);
console.log(barExecutionContext.findProperty("x")); // 1
전역 -> foo -> bar에서
전역의 x를 bar에서부터 찾는 동작을 코드로 나타냈다.