
자바스크립트의 실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다. 자바스크립트는 어떤 실행 컨텍스트가 활성화되는 시점에 다음과 같은 일을 한다.
- 선언된 변수를 위로 끌어올림 (호이스팅)
- 외부 환경정보 구성
- this 값 설정
실행 컨텍스트란 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.
그 객체. 즉, 동일 환경에 있는 코드를 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성하고 ‘스택’의 한 종류인 콜스택에 쌓아올린다.
가장 위에 쌓여있는 컨텍스트와 관련된 코드를 실행하는 방법으로 코드의 환경 및 순서를 보장할 수 있다.
현재 컨텍스트의 내부의 식별자 정보 environmentRecord, 외부 환경 정보 outerEnvironmentReference 가 포함되어 있다.
VariableEnvironment 에 먼저 정보를 담고, 그대로 LexicalEnvironment 에 복사해 사용한다.
environmentRecord
현재 컨텍스트와 관련된 식별자와 식별자에 바인딩된 값이 기록되는 공간이다.
더불어 실행 컨텍스트 내부 전체를 처음부터 끝까지 확인하며 순서대로 수집한다.
outerEnvironmentReference
현재 호출된 함수가 선언될 당시의 LexicalEnvironment 를 참조한다.
호이스팅
- 변수정보 수집을 모두 마쳤더라도 아직 실행 컨텍스트가 관여할 코드는 실행 전의 상태.(JS 엔진은 코드 실행 전 이미 모든 변수정보를 알고 있는 것)
- 변수 정보 수집 과정을 이해하기 쉽게 설명한 ‘가상 개념’
function a (x) { // 호이스팅 적용전
console.log(x);
var x;
console.log(x);
var x = 2;
console.log(x);
}
a(1);
function a () { // 매개변수 적용
var x = 1;
console.log(x);
var x;
console.log(x);
var x = 2;
console.log(x);
}
a(1);
function a () { // 호이스팅 적용 후
var x;
var x;
var x;
x = 1;
console.log(x);
console.log(x);
x = 2;
console.log(x);
}
a(1);
호이스팅을 생각하지 않았다면 결과를 1-> undefined -> 2로 처음엔 예상했겠지만, 호이스팅 적용후 1 -> 1 -> 2 라는 결과가 나오게된다.
호이스팅은 마찬가지로 함수 선언문 전체를 호이스팅 한다.
function a () { //호이스팅 적용 전
console.log(b);
var b = 'bbb';
console.log(b);
function b() { }
console.log(b);
}
a();
function a () {
var b; // 변수 선언부 호이스팅
function b() { } // 함수 선언은 전체를 호이스팅
console.log(b);
b = 'bbb'; // 변수의 할당부는 원래 자리에
console.log(b);
console.log(b);
}
a();
스코프 (Scope)와 스코프체이닝 (Scope chaining)
스코프란 식별자에 대한 유효 범위
스코프 체이닝은 식별자의 유효범위를 안에서부터 바깥으로 차례로 검색해나가는 것
var a = 1;
var outer = function() {
var inner = function() {
console.log(a); // undefined
var a = 3;
};
inner();
console.log(a); // 1
};
outer();
console.log(a); // 1
A함수 내부에 B함수 선언 → B함수 내부에 C함수 선언(Linked List)한 경우 어떻게 될까?전역 컨텍스트의 LexicalEnvironment를 참조한다.this 식별자가 바라보아야 할 객체
this는 실행 컨텍스트가 생성될 때 결정된다.
이 말을 this를 bind한다(=묶는다) 라고도 한다.
다시 말하면, this는 함수를 호출할 때 결정된다. 라고 할 수 있다.
메서드 에서 사용시 해당 메서드 가 담겨있는 instance or object 를 가르키며, 함수표현식에서 사용시 this 를 바인딩하지 않는 이상 전역 객체를 가르킨다.
ES6 의 화살표함수를 사용하면 this 바인딩, 우회법으로 변수에 this 를 담아 실행할 필요 없이 함수를 실행한 컨텍스트를 바라본다.
const obj = {
outer: function () {
console.log(this); // 메소드에서 사용되었기에 obj 출력
function inner() {
console.log(this); // 함수표현식에서 사용되었기에 전역객체 출력
}
inner();
const self = this;
function inner2() {
console.log(self); // 우회하기위해 this 를 self 에 할당, 출력하였기에 obj 출력
}
inner2();
const inner3 = () => {
console.log(this); // 화살표함수 사용으로 this 는 상위 스코프의 컨텍스트를 가르킴, obj 출력
};
inner3();
},
};
obj.outer();
// outer =>[object Object]
/// inner =>[object global]
// inner2 =>[object Object]
// inner3 =>[object Object]