본문 바로가기

Development/JavaScript

JS기초_보충(VE와 LE)

VE(VariableEnvironment)와 LE(LexicalEnvironment)의 개요

이 두가지에 담기는 항목은 완벽하게 동일하다. 스냅샷 유지 여부만 다르다.

  • VE : 스냅샷을 유지한다
  • LE : 스냅샷을 유지하지 않는다. 실시간으로 변경사항을 계속 반영한다.

즉, 실행 컨텍스트를 생성할 때 VE에 정보를 먼저 담은 다음, 이를 그대로 복사해서 LE를 만들고 이후에는 주로

LE를 활용한다.

 

구성 요소

  1. VE, LE 모두 동일하며 EnvironmentRecord와 OuterEvironmentReference로 구성
  2. EnvironmentRecord (=record)
    1. 현재 컨텍스트와 관련된 코드의 식별자 정보들 저장
    2. 함수에 지정된 매개변수 식별자, 함수자체, var로 선언된 변수 식별자 등
  3. OuterEvironmentReference (=outer)

 

LE - EnvironmentRecord - (=record)와 호이스팅

  1. 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장된다.
  2. 수집 대상 정보 : 함수에 지정된 매개변수 식별자, 함수 자체, var로 선언된 변수 식별자
  3. 컨텍스트 내부를 처음부터 끝까지 순서대로 훑어가며 수집

호이스팅(Hoisting)이란?

호이스팅의 사전적 의미는 '끌어올리다'이다.

자바스크립트에서 호이스팅이란 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미한다.

쉽게 말해서 코드를 위에서부터 차례로 실행한다고 예를 들었을 때 변수와 함수를 최상단으로 끌어올린다는 의미이다.

 

호이스팅 규칙

  1. 매개변수 및 변수는 선언부를 호이스팅한다.
  2. 함수 선언은 전체를 호이스팅한다.

호이스팅과 관련된 함수 사용 주의점

1. 함수 선언의 3가지 방식

// 함수 선언문. 함수명 a가 곧 변수명
// function 정의부만 존재, 할당 명령이 없는 경우
function a () { /* ... */ }
a(); // 실행 ok

// 함수 표현식. 정의한 function을 별도 변수에 할당하는 경우
// (1) 익명함수표현식 : 변수명 b가 곧 변수명(일반적 case에요)
var b = function () { /* ... */ }
b(); // 실행 ok

// (2) 기명 함수 표현식 : 변수명은 c, 함수명은 d
// d()는 c() 안에서 재귀적으로 호출될 때만 사용 가능하므로 사용성에 대한 의문
var c = function d () { /* ... */ } 
c(); // 실행 ok
d(); // 에러!

 

2. 주의할 점

호이스팅의 규칙을 토대로 생각했을 때 함수 선언문은 함수 전체를 위로 끌어올리고, 함수 표현식은 함수 선언부만 최상단으로 끌어올리기 때문에 길고 복잡한 코드에서는 치명적인 오류가 발생하기 쉽다. 따라서 가능하면 함수 표현식을 사용해야 한다.

 

 

LE - outerEnvironmentReference(=outer), 스코프, 스코프 체인

 

스코프

  • 식별자에 대한 유효범위를 의미
  • 대부분 언어에서 존재

스코프체인

  • 식별자의 유효 범위를 안에서부터 바깥으로 차례로 검색해 나가는 것

출처 : https://jess2.xyz/JavaScript/scope-chain-closure/

 

outerEnvironmentReference(= outer)

외부 환경의 참조 정보로 스코프 체인이 가능하도록하는 것이다.

 

정리하자면,

각각의 실행 컨텍스트는 LE 안에 record와 outer를 가지고 있고,

outer 안에는 그 실행 컨텍스트가 선언될 당시의 LE 정보가 다 들어있으니

스코프 체인에 의해 상위 컨텍스트의 레코드를 읽어올 수 있다.