현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보, 선언 시점의 LexicalEnvironment
의 스냅샷으로, 변경 사항은 반영되지 않음.
처음에는 VariableEnvironment
와 같지만 변경 사항이 실시간으로 반영
this
식별자가 바라봐야 할 대상 객체
LexicalEnvironment
와 같은 내용이지만 최초 실행 시의 스냅샷을 유지한다는 점이 다르다.
실행 컨텍스트를 생성할 때 VariableEnvironment
를 생성하고 이를 복사해 LexicalEnvironment
를 만들어 사용한다.
LexicalEnvironment
의 내부에는 environmentRecord
와 outerEnvironmentReference
로 구성돼 있다.
environmentRecord
에는 현재 컨텍스트와 관련된 코드의 식별자 정보가 저장된다.
식별자는 함수 매개변수 식별자, 함수 자체, var
로 선언된 변수의 식별자 등이 있고 위에서부터 아래로 탐색하면서 순서대로 수집한다.
이렇게 변수 수집 과정을 모두 마친 상태는 코드가 아직 실행되기 이전 상태다. 하지만 코드가 실행되기 이전에 자바스크립트 엔진은 이미 식별자들의 정보들을 가지고 있게 된다. 그리고 바로 여기서 발생하는게 호이스팅(Hoisting)이다.
호이스팅이란 변수나 함수의 선언부가 코드를 실행하기 전(함수 평가 과정)에서 자바스크립트 엔진에 의해 최상단으로 끌어올려지는 현상을 말한다.
자바스크립트 내의 모든 선언(Ex.let
, const
, var
, 함수
, class
등)는 Hoisting이 발생한다. let
, const
, class
등은 호이스팅이 일어나지만 코드 실행 과정에서 값이 할당되기 이전에 값을 읽으려고 하면 참조 에러가 발생하는데 이는 스코프의 시작부터 변수의 선언까지 일시적 사각 지대(Temporal Dead Zone, TDZ)에 빠지기 때문이다.
함수를 선언하는 방식은 함수 선언문과 함수 표현식이 존재한다.
함수 선언문은 function
정의부만 존재하고 별도의 할당 명령이 없는 것을 의미하고 함수 표현식은 정의한 function
을 별도의 변수에 할당하는 것을 말한다.
함수 선언문은 반드시 함수의 이름이 정의돼 있어야 하는 반면, 함수 표현식은 함수 이름이 없이 작성해도 된다.
그래서 함수 선언문을 '기명 함수 표현식', 함수 표현식은 '익명 함수 표현식'이라고 부르기도 한다.
또한 함수 선언문은 함수 전체를 호이스팅 하는 반면 함수 표현식은 변수 선언부만 호이스팅하게 된다. 자바스크립트에서 함수는 일급 객체로 취급되고 이러한 특성으로 인해 하나의 값으로 취급될 수 있다는 것이 바로 이런 점이다.
❗️ 일급 객체
일급 객체란 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다. 자바스크립트에서 함수는 일급 객체로 평가된다.일급 객체의 조건의 아래와 같다.
- 변수에 할당(assignment)할 수 있다.
- 다른 함수를 인자(argument)로 전달 받는다.
- 다른 함수의 결과로서 리턴될 수 있다.
함수가 일급 객체이기에 가능한 것은 아래와 같다.
- 고차함수(Higher order function)를 만들 수 있다.
- 콜백(callback)을 사용할 수 있다.
// 호이스팅이 일어나기 전
console.log(sum(1, 2));
console.log(multiply(3, 4));
function sum(a, b) {
return a + b;
}
var mutiply = function(a, b) {
return a * b;
}
// 호이스팅이 일어난 후
var sum = function sum(a, b) {
return a + b;
}
var mutiply;
console.log(sum(1, 2));
console.log(multiply(3, 4));
multiply = function (a, b) {
return a * b;
}
스코프란 식별자에 대한 유효 범위를 의미한다.
다른 언어와 달리 자바스크립트는 오직 함수에 의해서만 스코프가 생성된다. 이렇게 생성된 스코프(생성자의 유효 범위)를 안에서부터 바깥으로 차례로 탐색하는 것을 스코프 체인이라고 한다.
그리고 이를 가능하게 만들어 주는 것이 LexicalEnvironment
의 두 번째 수집 자료인 outerEnvironmentReference
이다.
현재 콜스택 최상단에 위치한 실행 컨텍스트가 활성화 될 때 LexicalEnvironment
의 outerEnvironmentReference
를 통해 점차 상위의 LexicalEnvironment
를 탐색하는 것이 스코프 체인이다. 이렇게 계속해서 상위 컨텍스트를 탐색하다보면 결국 전역 컨텍스트까지 올라가게 될 것이다.
만약 어떠한 식별자가 전역 컨텍스트에도 존재하고 현재의 컨텍스트에도 존재한다면 무조건 스코프 체인 상에서 먼저 발견된 식별자에만 접근이 가능하다.
이런 식으로 동일한 변수의 이름을 스코프 체인 상의 가까운 스코프에 선언하여 해당 변수에 접근할 수 없게 만드는 것이 변수 은닉화라고 한다.