실행 컨텍스트
실행할 코드에 제공할 정보들을 모아 놓은 객체
실행 컨텍스트의 동작
1) 동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트 구성
2) 컨텍스트들을 call stack에 쌓아 올려둠
3) 가장 위에 쌓여있는 컨텍스트와 관련 있는 코드들을 실행
4) 전체 코드의 환경과 순서 보장
// ------------------------- (1)
var a = 1;
function outer() {
function inner() {
console.log(a);
var a = 3;
// ------------------------- (2)
}
inner();// --------------- (3)
console.log(a);
// ------------------------- (4)
}
outer();
// ------------------------- (5)
console.log(a);
// ------------------------- (6)
실행순서는 (1) - (5) - (3) - (2) - (4) - (6)
💡 코드 실행 과정
1. 코드를 실행하는 순간 (1) 전역 컨텍스트가 콜 스택에 담긴다
2. 함수 호출문 outer()을 만나는 순간 해당 함수를 콜 스택에 추가한다.
3. 추가된 함수의 내부로 이동하여 코드들을 순차적으로 실행한다.
4. (3)에서 inner 함수의 실행 컨텍스트가 콜 스택의 최상단에 담기면 outer 컨텍스트와 관련된 코드의 실행을 중단하고 inner 함수 내부의 코드를 순차적으로 진행한다.
❗모든 코드가 콜스택에 처리되었으면 선입후출(FILO, First In Last Out)로 콜스택에서 실행한다.
5. 실행이 완료된 코드는 콜 스택에서 제거되고 아무것도 남지 않은 상태로 종료된다.
VariableEnvironment
LexicalEnvironment
ThisBinding
매개변수와 변수에 대한 호이스팅(1)
function a (x) { // -- 수집대상 1 (매개변수)
console.log(x); // (1)
var x; // -- 수집대상 2 (변수 선언)
console.log(x); // (2)
var x = 2; // -- 수집대상 3 (변수 선언)
console.log(x); // (3)
}
1, 1, 2
매개변수와 변수에 대한 호이스팅(2)
function a ( ) {
var x = 1; // -- 수집대상 1 (매개변수)
console.log(x); // (1)
var x; // -- 수집대상 2 (변수 선언)
console.log(x); // (2)
var x = 2; // -- 수집대상 3 (변수 선언)
console.log(x); // (3)
}
a();
매개변수와 변수에 대한 호이스팅(3)
function a () {
var x; // --------- 수집 대상 1(매개 변수)의 변수 선언 부분
var x; // --------- 수집 대상 2의 변수 선언 부분
var x; // --------- 수집 대상 3의 변수 선언 부분
x = 1; // --------- 수집 대상 1의 할당 부분
console.log(x); // (1)
console.log(x); // (2)
x = 2; // --------- 수집 대상 3의 할당 부분
console.log(x); // (3)
}
a();
함수 선언의 호이스팅(1)
function a() {
console.log(b); // (1)
var b = 'bbb'; // 수집 대상 1 (변수 선언)
console.log(b); // (2)
function b() {} // 수집 대상 2 (함수 선언)
console.log(b); // (3)
}
a();
function b() {}, bbb, bbb
함수 선언의 호이스팅(2)
function a() {
var b; // ------------ 수집 대상 1(변수 선언)의 선언 부분
function b() {} // --- 수집 대상 2(함수 선언)의 전체
console.log(b); // --- (1)
b = 'bbb'; // -------- 수집 대상 1의 할당 부분
console.log(b); // --- (2)
console.log(b); // --- (3)
}
a();
함수 선언문: function 정의부만 존재하고 별도의 할당 명령이 없는 것
함수 표현식: 정의한 함수를 별도의 변수에 할당하는 것
익명 함수 표현식: 함수명을 정의하지 않음
기명 함수 표현식: 함수명을 정의함
function a() { /* ... */ } // 함수 선언문. 함수명 a가 곧 변수명
a(); // 실행 가능
var b = function () { /* ... */ } // 익명 함수 표현식. 변수 b가 곧 함수명
b(); // 실행 가능
var c = function d() { /* ... */ } // 기명 함수 표현식. 변수명은 c, 함수명은 d
c(); // 실행 가능
d(); // 실행 불가능. 에러!
함수 선언문 예제
console.log(sum(3, 4)); // (1) : 7을 기대하지만, 3 + 4 = 7이 출력
function sum(x, y) { // -- 상단 함수
return x + y;
}
var a = sum(1, 2);
console.log(a); // ------- (2) : 3을 기대하지만, 1 + 2 = 3이 출력
function sum(x, y) { // -- 하단 함수
return `${x} + ${y} = ${x + y}`;
}
var c = sum(1, 2);
console.log(c); // ------- (3) : 1 + 2 = 3이 출력
함수 표현식 예제
// console.log(sum(3, 4)); // (1) : sum의 값이 없어서 undefined를 반환하기 때문에 에러!
var sum = function (x, y) { // -- 상단 함수
return x + y;
}
var a = sum(1, 2);
console.log(a); // ------- (2) : 3 출력
var sum = function (x, y) { // -- 하단 함수
return `${x} + ${y} = ${x + y}`;
}
var c = sum(1, 2);
console.log(c); // ------- (3) : 1 + 2 = 3이 출력