본문 바로가기
카테고리 없음

실행 컨텍스트

by cariño 2022. 9. 29.
728x90
반응형

* 해당 글은 코어자바스크립트 책을 기준으로 정리했습니다.

실행 컨텍스트 (Execution Context)

  • 함수를 실행할 때 필요한 (실행할 코드에 제공할) 환경 정보를 모아놓은 객체
    [객체 안의 구성]
    • Variable Environment : 최초에는 식별자 정보를 들고 있지만 그 값이 계속 변하지 않는다.
    • Lexical Environment : 실행 컨텍스트의 실행 내용에 따라 변수 값이 바뀔 때 그 변경 사항을 계속 트랙킹하는 정보이다.
      • environmentRecord : 현재 문맥의 식별자 (hoisting) = 호이스팅이라는 개념과 일치한다.
      • outerEnvironmentReference : 외부 식별자 (scope chain) = 외부 식별자 참조에 의해서 스코프체인이라는 개념이 생겼다.
    • thisBinding : this 식별자가 바라봐야 할 대상 객체
  • 실행 컨텍스트를 구성하는 방법은 함수를 실행하는 것뿐이다.

최상단 공간은 코드 내부에 별도 실행 명령이 없어도 브라우저에 의해서 자동으로 실행하므로 파일이 열리는 순간 전역 컨텍스트가 활성화 된다.

자바스크립트 엔진은 callstack을 통해서 전역컨텍스트 > 함수A 실행컨텍스트 > 함수A 안의 함수B 실행컨텍스트 실행

스택 구조는 한 실행 컨텍스트가 콜 스택 맨 위에 쌓이는 순간 곧 현재 실행할 코드에 관여하게 되는 시점이다.

 

 콜 스택 ?  현재 어떤 함수가 동작중인지 다음에 어떤 함수가 호출 될 예정인지 등을 제어하는 자료 구조이다.

 

실행 컨텍스트가 활성화될 때 js엔진은 해당 컨텐스트에 과련된 코드들을 실행하는데 필요한 환경 정보를 수집해서 실행 컨텍스트 객체에 저장한다.

 

[실행컨텍스트의 환경 정보 3가지]

variableEnvironment / lexicalEnvironment / ThisBinding

1. VariableEnvironment

  • 오직 식별자 정보를 수집하는 용도로만 쓰인다.
    - environmentRecord : 전체 코드를 스캔하면서 변수같은 정보를 실행컨텍스트 어딘가에 넣는다.
    • outerEnvironmentReference

2. LexicalEnvironment

  • 각 식별자에 담긴 '데이터'를 추적하는 용도로 쓰인다.
  • 컨텍스트 내부 코드들을 실행 하는 동안에 변수의 값에 변화가 생기면 LexicaEnvironment에만 실시간으로 반영된다.
  • 실행컨텍스트를 구성하는 환경 정보들을 모아 사전처럼 구성하는 객체
    - environmentRecord : 현재 컨텍스트 내부의 식별자 정보 / 식별자와 식별자에 바인딩된 값을 기록해두는 객체
    • outerEnvironmentReference : 외부 환경 참조하는 정보들이 담겨있다.

1). environmentRecord

[허구의 코드이지만 이렇게 이해해도 문제 될 건 없음]
function a() {
    return 'a'
} //호이스팅(1)
var b; //호이스팅(2)
var c; //호이스팅(3)

console.log(a())
console.log(b())
console.log(c())

b = function bb(){
    return 'bb'
}
c = function(){
    return 'c'
}
  • 실행 컨텍스트가 실행될 때 제일 먼저하는 일이 environmentRecord /현재 문맥의 식별자 정보를 수집하는 일이다.
  • 현재 컨텍스트에 식별자 정보들을 수집해서 environmentRecord에 담는 과정을 "호이스팅" 이라고 한다.
    • "호이스팅" : 식별자 정보를 실행 컨텍스트 맨 위로 끌어올린다.
      • 함수 선언문은 전체를 끌어 올린다.
      • 위에 끌어올려진 전체가 environmentRecord이다.

 

 

2). outerEnvironmentReference

  • 외부환경(Lexical Environment)에 대한 참조
  • 현재 문맥에 관련 있는 외부에 있는 컨텍스트의 식별자 정보를 참조한다. 
  • inner의 outerEnvironmentReference는 outer LexicalEnvironment 참조한다. outer안의 outerEnvironmentReference는 전역 LexicalEnvironment 참조한다.
  • 전역 LexicalEnvironment
    (environmentRecord)
  • outer LexicalEnvironment
    (environmentRecord / outerEnvironmentReference)
  • inner LexicalEnvironment
    (environmentRecord / outerEnvironmentReference)
  • outerEnvironmentReference는 scope chain이라는 것이다.
  • 스코프 체인은 외부환경참조에 의해서 만들어 지는 것이다.
  • SCOPE (변수의 유효범위)
    • 실행컨텍스트가 수집해 놓은 정보만 접근을 할 수가 있고, 그 변수는 실행컨텍스트 내부에서만 존재하는 것이다. 실행컨텍스트에 의해서 결정되는 것이다.
    • 외부로는 나갈 수 있지만 더 안쪽으로는 들어갈 수가 없다.
      - inner에서 선언한 변수들은 outer에서는 접근할 수가 없다. outer에서는 inner의 렉시컬환경에 대한 접근할 수 있는 수단이 없다. 참조하고 있는 대상이 없기때문.
  • SCOPE CHAIN? : 가장 가까이 있는 자신부터 점점 멀리 있는 스코프로 찾아 나가는것. 가장 먼저 찾아지는 것만 접근이 가능하다.
    - 가장 먼저 찾아지는 것만 접근할 수 있는 개념을 shadowing이라고 한다.

 

예시1) inner안에서 a의 값을 찾는다면 값은 1이 나온다. 
예시2) inner안에 a의 값이 없다면 inner에서는 outerEnviromentReference통해서 outer 실행컨텍스트에 접근할 수 있다. 그 다음에 있는 outer a의 값인 2가 나온다.

3. ThisBinding

  • 실행컨텍스트가 생성되는 순간에 this를 바인딩한다. (실행컨텍스트는 함수가 호출되는 순간에 생성된다.)
  • this는 함수가 호출될때 비로소 결정된다.
    • 함수를 어떤 식으로 호출했느냐에 따라서 this는 얼마든지 달라질 수 있다.
    • this는 함수가 호출하는 방식에 따라 다르기에 동적으로 바인딩된다.

[hoisting]

선언 라인 전에도 에러가 나지않고 변수를 선언할 수 있는 현상, 에러가 발생하지 않고 undefined가 출력된다.

[생성단계 Creation Phase]
Execution Context생성 / 선언문만 실행해서 Environment Record에 기록

[실행단계 Execution Phase]
선언문 외 나머지 코드 순차적으로 실행
Environment Record 참조하거나 업데이트

 

 

[변수 호이스팅]

  • var / let, const : 선언라인 이전에 식별자를 참조할 수 없는 구역
/*global*/
console.log(TVChannal) //undefined
var TVChannal = 'netflix'
console.log(TVChannal) //netflix

 

 

/*global*/
console.log(TVChannal) //Reference Error
const TVChannal = 'netflix'
console.log(TVChannal) //netflix

 

 

[함수 호이스팅]

  • 함수 표현식 : 함수를 변수에 담아서 사용/ 변수 호이스팅과 동일하게 동작
study() // undefined
var study = () =>{ //do study }
callstack : {study : undefined}
study() // Reference Error
const study = () =>{ //do study }
callstack : {study : undefined}
  • 선언문 이전에 var키워드 함수를 실행하면 환경레코드에 기록되어있는 study의 값은 undefinend이고 undefined라는 데이터타입은 함수와 달리 호출될 수 없기 때문에 타입에러 발생한다.
  • const키워드의 경우 아직 환경레코드에 기록된 값이 없어 reference error가 발생한다.
  • 함수 표현식 function Expression
var { study : undefined}
let const {study} 
  • 함수 선언문 Function Declaration
{study: f{} }

변수에 담지 않고 선언과 동시에 함수가 생성.

728x90

댓글