PracticeEveryday

JavaScript 본문

JavaScript

JavaScript

kimddakki 2022. 5. 19. 16:50
실행 컨텍스트

 - 실행할 코드에 제공할 환경 정보들을 모아 놓은 객체

 - 자바스크립트의 동적 언어로서의 성격을 가장 잘 파악할 수 있는 개념

 

자바스크립트는 실행 컨텍스트가 활성화 되는 시점에 다음과 같은 현상이 발생한다.

 - 호이스팅이 발생한다 ( 선언된 변수를 위로 끌어 올린다. )

 - 외부 환경 정보를 구성한다.

 - this 값을 설정한다.

 

실행 컨텍스트 구성

 

 - 실행 컨텍스트는 다음과 같은 것들을 이용하면 call stack에 쌓이게 된다.

 

 - 전역 공간은 자동으로 컨텍스트로 구성된다.

 - 함수를 실행한다.

 - eval() 함수를 만든다.

 - block을 만든다.

 

// 일반적으로 함수를 이용한 실행 컨텍스트를 사용한다.

var a = 1; // 전역 컨텍스트

function outer() {
  // outer context
  function inner() {
    // inner c
    console.log(a); // 3

    var a = 3;
    console.log(a); // 1
  }
  inner();
  console.log(a); // 1
}

outer();
console.log(a);

 - 위와 같은 코드를 구성했을 때 실행 컨텍스트의 스택은 다음과 같은 순서로 실행된다.

 

 - 프로그램 실행 : 전역 컨텍스트

 - outer 실행 : 전역 컨텍스트 ,outer

 - inner 실행 : 전역 컨텍스트, outer, inner

 - inner 종료 : 전역 컨텍스트, outer

 - outer 종료 : 전역 컨텍스트

 

※ 실행 컨텍스트를 구성할 때 생기는 것들

1. VariableEnvironment

 - 현재 컨텍스트 내의 식별자(변수)들에 대한 정보

 - 외부 환경 정보

 - 선언 시점의 LexicalEnvironment의 스냅샷 ( 변경 사항 반영 x )

2. LexicalEnvironment

 - 처음에는 VariableEnvironment와 같음

 - 변경 사항이 실시간으로 반영됨

3. ThisBinding

 - 식별자가 바라봐야 할 대상 객체

 

Variable: 변수 Environment

 - VariableEnvironment에 담기는 내용은 LexicalEnvironment와 같지만, 최초 실행 시의 스냅샷을 유지한다.

 - 실행 컨텍스트를 생성할 때 VariableEnvironment에 정보를 먼저 담은 다음, 이를 복사해서 LexicalEnvironment를

   만든다.

 

주로 활용하는 것은 LexicalEnvironment이다. 즉, VariableEnviroment는 스냅샷 유지를 목적으로 사용한다.

 

Lexical Environment

 - LexicalEnvironment의 내부에는 environmentRecord outerEnvironmentReference로 구성돼 있다.

 

 - environmentRecord로 인하여 호이스팅이 발생한다.

 - outerEnvironmentReference로 인하여 스코프와 스코프체인이 형성된다.

 

environmentRecord와 Hoisting( 호이스팅 )

 - 자바스크리트는 코드를 실행하기 전에 식별자를 수집한다.

EnvironmentRecord

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

매개변수 식별자
함수 자체
함수 내부의 식별자

Host Object( 호스트 객체 )

전역 실행 컨텍스트는 변수 객체를 생성하는 대신 전역 객체를 활용한다.
브라우저의 Window 객체, Node의 Global 객체 등이 이에 해당된다.
이들은 Host Object로 분류된다.

 => 즉 코드가 실행되기 전에 자바스크립트의 엔진은 이미 실행 컨텍스트에 속한 변수명을 모두 알고 있게 되는 셈이다.

      // 이때 호이스팅이란 개념이 이용된다.

 

 - 엔진의 실제 동작 방식 대신에 자바스크립트 엔진은 식별자들을 최상단으로 끌어올려놓은 다음, 실제 코드를

   실행한다. 라고 생각해도 코드 해석에 문제되는 것이 없기 때문이다.

   => 중요한 점은 자바스크립트 엔진이 실제로 변수를 끌어올리지는 않지만, 편의상 끌어올리는 것으로 간주하자는

        것이다.


변수의 호이스팅
function func(x) {
  console.log(x); // 1
  var x;
  console.log(x); // 1
  var x = 2;
  console.log(x); // 2
}

func(1);

위 코드는 다음과 같이 해석될 수 있다.

function a () {
  var x = 1; // 매개변수 할당
  console.log(x);
  var x ;
  console.log(x);
  var x = 2;
  console.log(x);
}

a();

다시 위의 코드에서 호이스팅이 발생한다고 가정하면, 다음과 같이 해석할 수 있다.

function a () {
  var x;
  var x;
  var x;

  x = 1;
  console.log(x); // 1
  console.log(x); // 1
  x = 2;
  console.log(x); // 2
}
a();

함수의 호이스팅
function a() {
  console.log(b); // function b
  var b = "bbb";
  console.log(b); // bbb
  function b() {}
  console.log(b); // bbb
}
a();

변수의 경우 정의부만 호이스팅 되지만, 함수는 함수 전체가 호이스팅 된다.

function a() {
  var b;
  function b() {}

  console.log(b); // function b
  b = "bbb";
  console.log(b); // bbb
  console.log(b); // bbb
}
a();

자바스크립트의 함수는 일급객체 (or 일급시민) 이기에 함수 표현식이 가능하다.

더보기

일급객체(일급시민)

여기 x라는 것이 있다.

  • x를 변수에 담을 수 있다.
  • x를 매개변수에 넘길 수 있다.
  • x를 함수에서 반환할 수 있다.

x를 만족할 때, 이를 일급객체라고 한다.

즉, 자바스크립트의 함수는 일급객체이므로

  • 함수를 변수에 담을 수 있다.
  • 함수를 매개변수로 넘길 수 있다.
  • 함수를 함수에서 반환할 수 있다.

위의 같은 조건을 만족한다.

function a() {
  console.log(b); // undefined
  var b = "bbb";
  console.log(b); // bbb
  var b = function () {}; // b에 익명함수를 할당했다.
  console.log(b); // function b
}
a();

위의 코드는 아래와 같다.

function a() {
  var b;
  var b;

  console.log(b); // undefined
  b = "bbb";
  console.log(b); // bbb
  b = function () {}; // b에 익명함수를 할당했다.
  console.log(b); // f () {}
}
a();

outerEnvironmentReference와 Scope
scope

스코프란 식별자에 대한 유효범위이다.

Scope A의 외부에서 선언한 변수는, A의 외부/ 내부 모두 접근 가능하다.
A의 내부에서 선언한 변수는 오직 A의 내부에서만 접근 할 수 있다.

스코프의 개념은 대부분의 언어에서 존재하지만, ES5까지의 JavaScript는 오직 함수에 의해서만 스코프가 생성된다.

Scope Chain
식별자의 유효범위를 안에서 바깥으로 차례로 검색해나가는 것
이를 가능하게 하는 것이 outerEnvironmentReference이다.

 - outerEnvironmentReference는 현재 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조한다.

 - 선언하다라는 행위가 실제로 일어날 수 있는 시점은 콜 스택 상태에서 어떤 실행 컨텍스트가 활성화 된 상태뿐이다.

   모든 코드는 실행 컨텍스트가 활성화 상태일 때 실행되기 때문이다.

var a = 1; // 전역 컨텍스트
function outer() {
  // outer 컨텍스트
  function inner() {
    // inner 컨텍스트
    console.log("1 :", a); // 1: undefined
    var a = 3;
    console.log("2 :", a); // 2 : 3
  }
  inner();
  // inner가 실행될 때 outer의 LexcicalEnvironemnt를 outerEnvironmentReference로 참조한다.
  console.log("3 :", a); // 3: 1
}

outer();
// outer가 실행될 때 전역 컨텍스트의 LexcicalEnvironemnt를 outerEnvironmentReference로 참조한다.
console.log("4 :", a); // 4: 1

위 코드의 scope chain은 아래와 같다.

inner LexicalEnvironment {
    식별자 a
    outerEnvironmentReference = outer LexicalEnvironment {
            식별자 a
            outerEnvironmentReference = global LexicalEnvironment {
                식별자 a
            }
        }
    }
}

이와 같은 구조적 특성 덕분에 여러 스코프에서 동일한 식별자를 선언할 경우,

무조건 Scope Chain 상에서 가장 먼저 발견된 식별자에만 접근 가능 하게 된다.

 

inner LexicalEnvironment {

    식별자 a        # inner function에서 a에 접근할 때 여기에 가장 먼저 접근

    outerEnvironmentReference = outer LexicalEnvironment {

            식별자 a        # outer function에서 a에 접근할 때 여기에 가장 먼저 접근
            식별자 b        # inner function에서 b에 접근할 때 여기에 가장 먼저 접근

            outerEnvironmentReference = global LexicalEnvironment {

                식별자 a        # 전역에서 a에 접근할 때 여기에 가장 먼저 접근
                식별자 b        # 전역에서 b에 접근할 때 여기에 가장 먼저 접근
                식별자 c        # inner function에서 c에 접근할 때 여기에 가장 먼저 접근

            }

        }

    }

}

 

실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다
 - 전역 공간에서 자동으로 생성되는 전역 컨텍스느
 - eval 함수
 - 함수 실행에 의한 컨텍스트
 
실행 컨텍스트 객체는 활성화 되는 시점에 VariableEnvironment, LexicalEnvironment, ThisBinding의 세가지 정보를 수집한다.
실행 컨텍스트를 생성할 때 VariableEnvironment와 LexicalEnvironment가 동일한 내용으로 구성된다.

LexicalEnvironment는 함수 실행 도중에 변경되는 사항이 즉시 반영된다.
LexicalEnvironment와 VariableEnvironment는 environmentRecord와 outerEnvironmentReference로 구성되어 있다.
 - 이것 때문에 hoisting이란 개념이 사용된다.
 - 호이스팅은 코드 해성을 좀 더 수월하게 하기 위해 environmentRecord의 수집 과정을 추상화한 개념이다.
 - 변수 선언부와 함수 선언문에 호이스팅이 발생한다.
 - 함수 표현식을 사용할 경우 함수의 선언부만 호이스팅이 발생한다.

outerEnvironmentReference는 상위(직전)) 컨텍스트의 LexicalEnvironment 정보를 참조한다.
 - 이것 때문에 scope가 형성되고 스코프 체인을 통해 상위 컨텍스트에 접근할 수 있다.
 - 스코프는 변수의 유효범위를 이야기한다.

 

 

자바스크립트 실행 컨텍스트 | 개발자 황준일

자바스크립트 실행 컨텍스트 실행 컨텍스트는 자바스크립트에서 가장 중요한 핵심 개념 중에 하나다. 이를 정확히 이해하는 것은 자바스크립트 개발자에게 매우 중요하다. 1. 개념 실행 컨텍스

junilhwang.github.io

 

'JavaScript' 카테고리의 다른 글

JavaScript  (0) 2022.06.02
JavaScript  (0) 2022.05.25
JavaScript  (0) 2022.05.18
JavaScript  (0) 2022.05.18
JavaScript  (0) 2022.05.18
Comments