[JS] environmentRecord와 호이스팅

cabbage·2023년 4월 12일

JS

목록 보기
27/43
post-thumbnail

저번 주제로 작성했던 실행 컨텍스트의 구성 요소에 이어서 실행 컨텍스트 구성 요소 중 하나인 LexicalEnvironment의 environmentRecord와 호이스팅에 대해 작성한다.

LexicalEnvironment

저번 주제에서 작성했던 대로 LexicalEnvironment는 실행 컨텍스트의 구성 요소 중 하나로, 실행 컨텍스트를 구성하는 환경 정보들을 모아놓은 것이다. 그리고 LexicalEnvironment는 2개의 구성 요소를 갖는다.

  • environmentRecord
  • outerEnvironmentRecord(outer 참조)

여기서 이번 주제인 environmentRecord는 식별자 관련 정보를 저장한다고 하였다.

environmentRecord와 호이스팅

environmentRecord에는 실행 컨텍스트와 관련된 코드의 식별자 정보들이 저장된다.

식별자 정보란 실행 컨텍스트를 구성하는 함수에서 선언한 매개변수, 함수, var로 선언된 변수 등의 정보를 말한다. 자바스크립트 엔진은 함수 실행 컨텍스트의 내부 전체를 처음부터 끝까지 훑어 순서대로 수집한다.

자바스크립트 엔진이 변수 정보를 수집하는 과정을 모두 마치더라도 함수 실행 컨텍스트를 생성하는 함수 코드들은 아직 실행되기 전이다. 함수 코드들이 실행되지 않았지만 자바스크립트 엔진은 이미 함수 실행 컨텍스트 환경에 어떤 변수들이 포함되어 있는지를 알고 있다는 것이다.

여기서 자바스크립트의 '호이스팅' 개념이 등장한다. 자바스크립트 엔진의 변수 정보를 수집하는 과정을 이해하기 쉬운 방법으로 대체한 가상의 개념이다. (자바스크립트 엔진은 실제로 변수를 호이스팅하지 않지만 이해하기 쉽게 호이스팅한다고 간주한다는 것)

호이스팅 규칙

environmentRecord에는 매개변수명, 함수 선언, 변수명 등이 담긴다.

자바스크립트 엔진이 호이스팅(변수 정보 수집 과정)을 수행하면 environmentRecord에는 매개변수명, 함수 선언, 변수명 등이 담기게 된다.

호이스팅 예제 코드

function a (x) {  // 매개변수 x: 변수 수집 대상1
  console.log(x);
  var x;          // 변수선언 x: 변수 수집 대상2
  console.log(x);
  var x = 2;      // 변수선언 x: 변수 수집 대상3
  console.log(x);
}
a(1);
  • 함수 a를 호출하면 자바스크립트 엔진은 함수 코드를 실행하기 전에 함수 a 실행 컨텍스트를 생성한다.
  • 함수 a 실행 컨텍스트의 LexicalEnvironment를 구성하면서 함수 코드를 처음부터 끝까지 훑어 변수 정보를 수집(호이스팅)해 environmentRecord에 저장한다.
function a () {
  var x = 1;      // 매개변수 x: 변수 수집 대상1
  console.log(x);
  var x;          // 변수선언 x: 변수 수집 대상2
  console.log(x);
  var x = 2;      // 변수선언 x: 변수 수집 대상3
  console.log(x);
}
a();
  • a(1)과 같이 아규먼트를 전달해 함수를 호출한 경우, 위에 있는 코드처럼 함수 내부의 다른 코드들보다 아규먼트를 먼저 선언하고 할당한 것으로 간주할 수 있다. (실제로 바꾸는 것은 아님)
function a () {
  var x;  // 수집 대상 1의 변수 선언 부분
  var x;  // 수집 대상 2의 변수 선언 부분
  var x;  // 수집 대상 3의 변수 선언 부분

  x = 1;           // 수집 대상 1의 할당 부분
  console.log(x);  // 1
  console.log(x);  // 1
  x = 2;           // 수집 대상 3의 할당 부분
  console.log(x);  // 2
}
a(1);
  • environmentRecord는 현재 실행 컨텍스트의 코드 내에 어떤 식별자들이 있는지에만 관심을 갖는다. 변수를 호이스팅할 때 변수 선언부만 호이스팅하고 할당부는 원래 자리에 그대로 둔다. (매개변수도 마찬가지)

함수 선언을 추가한 호이스팅 예제 코드

function a () {
  console.log(b);
  var b = 'bbb';     // 수집 대상 1(변수 선언)
  console.log(b);
  function b () [}   // 수집 대상 2(함수 선언)
  console.log(b);
}
a();
  • 함수 a를 실행하면 함수 a 실행 컨텍스트가 생성된다. 이때 호이스팅(변수 정보 수집 과정)을 진행한다.
  • 호이스팅 과정에서 변수명과 함수 선언 정보를 호이스팅하여 수집한다.
function a () {
  var b;
  function b () {}

  console.log(b);
  b = 'bbb';
  console.log(b);
  console.log(b);
}
a();
  • 변수는 선언부와 할당부를 구분하여 선언부만 호이스팅한다.
  • 하지만 함수 선언은 함수 전체를 호이스팅한다.
function a () {
  var b;
  var b = function b () {};

  console.log(b); // ƒ b()
  b = 'bbb';
  console.log(b); // bbb
  console.log(b); // bbb
}
a();
  • 호이스팅 이후 함수 선언문은 함수명으로 선언한 변수에 함수를 할당한 것처럼 간주할 수 있다.

정리

  • environmentRecord에는 매개변수명, 함수 선언, 변수명 등이 담긴다.
  • 함수 코드 실행 전이라도 자바스크립트 엔진은 이미 함수 실행 컨텍스트 환경에 어떤 변수들이 포함되어 있는지를 알고 있다.
  • 호이스팅은 자바스크립트 엔진의 변수 정보를 수집하는 과정을 이해하기 쉬운 방법으로 대체한 가상의 개념이다.
  • 자바스크립트 엔진은 실행 컨텍스트의 LexicalEnvironment를 구성하면서 함수 코드를 처음부터 끝까지 훑어 변수 정보를 수집(호이스팅)해 environmentRecord에 저장한다.
  • 변수를 호이스팅할 때 변수명만 호이스팅하고 할당 과정은 원래 자리에 그대로 둔다.
  • 함수 선언은 함수 전체를 호이스팅한다.

참고

  • 코어 자바스크립트 - 정재남
profile
캐비지 개발 블로그입니다. :)

0개의 댓글