JS 3-6. 실행 컨텍스트, Variable Environment, Lexical Environment, 스코프 체인, this

강연주·2024년 11월 26일

🙋‍♀️ 기술면접

목록 보기
67/112

21. 실행 컨텍스트와 구성 요소 VariableEnvironment, LexicalEnvironment 역할과 차이점 설명, 스코프 체인과 this 설명

실행 컨텍스트는 JavaScript 코드가 실행되는 동안 생성되는 환경으로,
코드의 실행에 필요한 정보를 담고 있다. 실행 컨텍스트는 크게 세 가지 요소로 구성된다.

  • VariableEnvironment
  • LexicalEnvironment
  • this 바인딩

VariableEnvironment와 LexicalEnvironment 모두 환경 레코드(Environment Record)와 외부 렉시컬 환경에 대한 참조(Outer Lexical Environment Reference)를 가지고 있다. 이 둘은 매우 유사하지만, 사용 목적에 따라 약간의 차이가 있다.

LexicalEnvironment

  • 역할
    현재 실행 중인 코드의 식별자(변수, 함수, 매개변수 등)를 저장하고,
    스코프 체인을 형성한다.
  • 특징
    • 변수나 함수의 스코프를 결정하는 데 사용된다.
    • 식별자를 해석할 때 참조되는 환경.
    • 블록 스코프(let, const)와 함수 스코프를 모두 포함.

VariableEnvironment

  • 역할 : 함수 내에서 변수 선언을 처리할 때 사용.
  • 특징
    • 주로 var로 선언된 변수의 호이스팅을 관리.
    • 초기 실행 시점에 변수와 함수 선언을 수집한다.

차이점

  • 사용 시점
    • LexicalEnvironment는 런타임에 식별자를 해석할 때 사용.
    • VariableEnvironment는 초기화 단계에서 변수와 함수 선언을 등록할 때 사용.
  • 블록 스코프 처리
    • LexicalEnvironment는 블록 스코프(let, const)를 지원한다.
    • VariableEnvironment는 함수 스코프(var)만을 처리한다.

🪶 스코프 체인(Scope Chain)

스코프 체인은 렉시컬 환경의 연속적인 연결로, 식별자를 찾을 때
현재 렉시컬 환경에서 시작하여 상위 환경으로 이동하면서 검색한다.

동작 방식
1. 식별자를 해석할 때 현재 LexicalEnvironment에서 찾는다.
2. 찾지 못하면 외부 렉시컬 환경으로 이동하여 검색한다.
3. 전역 환경까지 이동해도 찾지 못하면 ReferenceError 발생.

🖥️ javascript

function outer() {
  let a = 1;
  function inner() {
    console.log(a); // 스코프 체인을 통해 a를 찾습니다.
  }
  inner();
}
outer();

inner 함수의 LexicalEnvironment에는 a가 없으므로
외부의 outer 함수의 LexicalEnvironment에서 a를 찾는다.


🪼 this 바인딩

this 바인딩은 실행 컨텍스트에서 현재 실행 중인 코드의 문맥(context)을 나타낸다.
this는 함수 호출 방식에 따라 값이 결정된다.

this의 결정 방식

  • 전역 컨텍스트
    전역 코드에서 this는 전역 객체를 가리킨다.
    (브라우저에서는 window, Node.js에서는 global)

  • 함수 컨텍스트

    • 일반 함수 호출 : 전역 객체 (strict mode에서는 undefined)
    • 메서드 호출 : 메서드를 소유한 객체
  • 생성자 함수 호출 (new 키워드 사용) : 새로 생성된 인스턴스 객체

  • call, apply, bind를 사용한 호출 : 명시적으로 지정한 객체

🖥️ javascript

function foo() {
  console.log(this);
}

foo(); // 전역 객체 (strict mode에서는 undefined)

const obj = {
  foo: foo
};

obj.foo(); // obj 객체

new foo(); // 새로 생성된 객체

foo.call(obj); // obj 객체
profile
아무튼, 개발자

0개의 댓글