실행 컨텍스트
실행 컨텍스트
는 실행할 코드에 제공할 환경 정보
들을 모아놓은 객체
이다.
자동으로 생성되는 전역공간과 eval을 제외하면, 우리가 실행 컨텍스트를 구성하는 방법은 함수를 실행하는 것 뿐이다.
실행 컨텍스트 객체는 자바 스크립트 엔진이 활용할 목적으로 생성할 뿐, 개발자가 코드를 통해 확인할 수는 없다.
실행 컨텍스트에 담기는 정보는 아래와 같다.
VariableEnvironment
현재 컨텍스트 내의 식별자들에 대한 정보, 외부 환경 정보, 선언 시점의 LexicalEnvironment의 스냅샷
변경 사항은 반영되지 않는다.
LexicalEnvironment
처음에는 VariableEnvironment와 같지만 변경 사항이 실시간으로 반영된다.
ThisBinding
this 식별자가 바라봐야 할 대상 객체
VariableEnvironment
실행 컨텍스트를 생성할 때, VariableEnvironment에 정보를 먼저 담고, 이를 그대로 복사하여 LexicalEnvironment를 만든 후, 이 이후에는 LexicalEnvironment를 주로 활용하게 된다.
초기에는 두 개가 완전히 동일하지만 코드 진행에 따라 서로 달라지게 된다.
LexicalEnvironment
environmentRecord에는 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장된다.
매개변수 식별자, 선언한 함수가 있는 경우 함수 자체, var로 선언된 변수의 식별자 등이 해당한다.
컨텍스트 내부 전체를 처음부터 끝까지 쭉 훑어나가며 순서대로
수집한다.
이런 정보를 모두 수집하는 과정을 마쳤지만, 아직 실행 컨텍스트가 관여할 코드들은 실행되지 전인 상태이다.
바꾸어 말하면, 실행되기 전임에도 자바 스크립트 엔진은 이미 해당 환경의 변수명을 모두 알고 있게 된다.
이것이 호이스팅이다.
environmentRecord는 현재 실행될 컨텍스트의 대상 코드 내에 어떤 식별자들이 있는지에만 관심이 있고, 각 실별자에 어떤 값이 할당될 것인지는 관심이 없다.
따라서 변수를 호이스팅할 때, 변수 명만 끌어올리고 할당 과정은 원래 자리에 그대로 남겨둔다.
function sum(a, b) {
return a+b;
}
var multiply = funtion(a, b) {
return a*b;
}
위와 같이 코드를 작성한 경우에 sum과 같은 방법을 함수 선언문, multiply와 같은 방법을 함수 표현식이라고 한다.
둘 모두 호이스팅이 일어나지만 그 방식이 다르다.
sum의 경우, 함수의 body까지 전체가 메모리에 올라가게 된다.
multiple의 경우, 변수명이자 함수명인 multiply만 메모리에 미리 올라가고, body는 할당되지 않는다.
만일, 아래와 같이 작성한다고 하자.
console.log(sum(1,2)); // 3
console.log(multiply(1,2)); // Error: multiple is not a function
function sum(a, b) {
return a+b;
}
var multiyple = function(a, b){
return a*b;
}
sum은 전체가 호이스팅 되어 선언 전에도 사용이 가능하지만, multiple의 경우에는 그 내용이 아직 할당되기 전이므로 오류가 발생한다.
sum과 같은 함수 선언문의 경우, 혹여라도 코드 하단에서 sum을 재정의 하였을 때, 가장 나중에 할당한 값을 덧씌우는 호이스팅의 특성 상 의도하지 않은 방식으로 동작할 가능성이 있다.
따라서 호이스팅의 시점과 할당의 시점을 다르게 하는 함수 표현식이 권고된다.