TIL 51 day 2장 실행 컨텍스트

Winney·2020년 12월 19일
0

코어자바스크립트

목록 보기
2/6
post-thumbnail

사전 지식

스택(stack)과 큐(queue)

  • 스택(stack) : 출입구가 하나인 깊은 우물모양
    In: A, B, C, D => Out: D, C, B, A
  • 큐(queue) : 양쪽이 모두 열려있는 파이프
    In: A, B, C, D => Out: A, B, C, D

실행 컨텍스트

  • 실행할 코드에 제공할 환경 정보들을 모아놓은 객체 => JS의 동적 언어의 성격
  • 함수를 실행하는 것이 흔한 실행 컨텍스트를 구성하는 방법
    • 호이스팅(hoisting) : 실행 컨텍스트가 활성화 되는 시점에 선언된 변수를 위로 끌어올린다.
    • 외부 환경 정보를 구성
    • this 값을 설정
  • 어떤 실행 컨텍스트가 활성화될 때 JS 엔진은 해당 컨텍스트에 관련된 코드들을 실행하기위해 필요한 환경 정보들을 수집해서 실행 컨텍스트 객체에 저장
    • VariableEnvironment : 현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보, 선언 시점의 LexicalEnvironment의 스냅샷으로 변경사항은 저장되지 않음
    • LexicalEnvironment : 처음에는 VariableEnvironment와 같지만 변경 사항이 실시간으로 반영
    • ThisBinding: this 식별자가 바라봐야 할 대상 객체
  • VariableEnvironment 및 LexicalEnvironment의 내부는 environmentRecord와 outerEnvironmentReference로 구성

LexicalEnvironment

environmentRecord 와 호이스팅(hoisting)

  • environmentRecord : 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장

    -컨텍스트에 구성된 함수에 지정된 식별자(매개변수의 이름)
    -선언한 함수가 있을 경우 그 함수 자체(함수 선언)
    -var로 선언된 변수의 식별자(변수명)

위의 것들이 코드의 순서대로 수집이 된다.

  • 호이스팅(hoisting) : 코드가 실행 되기 전 이지만 JS 엔진은 이미 해당 환경에 속한 코드의 변수명을 모두 알게됨. 그렇다면 엔진의 실제 동작 방식 대신 JS 엔진은 식별자들을 최상단으로 끌어올려놓은 다음 실제 코드를 실행한다고도 말 할 수 있다.

  • environmentRecord
    : 현재 실행 될 컨텍스트의 대상 코드 내에 어떤 식별자가 있는지만 관심 => 값 할당에 관심 X
    즉, 변수를 호이스팅 할 때 변수명만 끌어올리고 할당 과정은 원래자리에 위치

  • 호이스팅이 끝난 상태의 함수 선언문은 함수명으로 선언한 변수에 함수를 할당한 것처럼 여겨질 수 있다. (46p 예제 2-6, 예제 2-7)

함수 선언문과 함수 표현식

함수 선언문(function declaration)

  • function 정의부만 존재하고 변도의 할당 명령이 없는 것
  • 반드시 함수명이 정의

함수 표현식(function expression)

  • 함수 표현식은 정의한 function을 변도의 변수에 할당하는 것
  • 함수명 없어도 됨

동일한 변수명에 서로 다른 값을 할당 할 경우 나중에 할당한 값이 먼저 할당한 값을 덮어씌운다.(override) 실제로 호출되는 함수는 오직 마지막에 할당한 마수, 즉 맨 마지막에 선언된 함수만 호출된다.

스코프, 스코프 체인, outerEnvironmentReference

스코프(scope)

  • 식별자에 대한 유효범위

스코프체인(scope-chain)

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

    LexicalEnvironment의 두번째 수집자료인 outerEnvironmentReference가 이를 가능하게 한다.

  • outerEnvironmentReference는 현재 호출된 함수가 선언될 당신의 LexicalEnvironment 참조한다.
    '선언하다'의 행위가 실제 일어 날 수 있는 시점 => 콜 스택 상에서 어떤 실행 컨텍스트가 활성화된 상태
    모든 코드는 실행 컨텍스트가 활성화 상태일 때 실행되기 때문
    ex) 함수 A 내부에 함수 B 선언, 함수 B 내부에 함수 C가 선언

  1. 함수 C의 outerEnvironmentReference는 함수 B의 LexicalEnvironment를 참조
  2. 함수 B의 LexicalEnvironment에 있는 outerEnvironmentReference는 함수 B가 선언되던 때인 함수 A의 LexicalEnvironment 참조
  • outerEnvironmentReference는 연결리스트(linked list) 형태를 가진다.
    => 최종적으로는 전역 컨텍스트의 LexicalEnvironment가 있을 것.
  • 각 outerEnvironmentReference는 오직 자신이 선언된 시점의 LexicalEnvironment만 참조
    => 가장 가까운 요소부터 차례로만 접근 가능하다.
    여러 스코프에서 동일한 식별자를 선언한 경우 무조건 스코프 체인 상에서 가장 먼저 발견된 식별자에만 접근 가능
var a = 1;
var outer = function() {
  var inner = function() {
    console.log(a);
    var a = 3;
  };
  inner();
  console.log(a);
};
outer();
console.log(a);

inner 함수 내부에서 a에 접근할 경우 무조건 스코프 체인 상의 첫 번째 인자 즉, inner 스코프의 LexicalEnvitonment부터 검색할 수밖에 없다.
inner 함수 내부에서 a 변수를 선언했기 때문에 전역 공간에서 선언한 동일한 이름의 a 변수에는 접근할 수 없다
=> 변수 은닉화(variable shadowing)

profile
프론트엔드 엔지니어

0개의 댓글

관련 채용 정보