실행컨텍스트란?

신은수·2023년 4월 11일
0

VanillaJS

목록 보기
4/11
post-thumbnail

1. 실행컨텍스트

1) 실행컨텍스트란?

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

2) 실행 컨텍스트와 콜스택

  • 동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성하고, 이를 콜 스택에 쌓아올렸다가, 가장 위에 쌓여있는 컨텍스트와 관련있는 코드들을 실행하는 식으로 전체 코드의 환경과 순서를 보장

    var a = 1;
     function outer(){
        function inner(){
          console.log(a); 
          var a = 3; 
        }
        inner(); 
        console.log(a); 
     }
    
     outer(); 
     console.log(a); 

3) 실행컨텍스트 객체에 담기는 정보 3가지

  • VariableEnvironment

    • 현재 컨텍스트 내의 식별자들에 대한 정보 (EnvironmentRecord)

    • 외부환경 정보(OuterEnvironmentReference)

  • LexicalEnvironment: 처음에는 VariableEnvironment와 같지만 변경사항이 실시간 반영됨

  • ThisBinding: this 식별자가 바라봐야할 대상 객체

2. LexicalEnvironment

1) EnvironmentRecord와 호이스팅

a) 호이스팅 기초

  • EnvironmentRecord에는 현재 컨텍스트와 관련된 코드의 식별자 정보(매개변수, 선언한 함수)들이 저장됨

  • 컨텍스트 내부 전체를 처음부터 끝가지 쭉 훑어나가며 순서대로 수집.

  • 코드 실행 전에 자바스크립트 엔진은 이미 해당 환경에 속한 코드의 변수명을 모두 알고 있는 셈

  • 따라서 '자바스크립트 엔진은 식별자들을 최상단으로 끌어올려놓은 다음 실제 코드를 실행한다' 라고 생각해도 괜찮음. => 호이스팅

  • 문제)

    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
      }

    해설) environmentRecord는 현재 실행될 컨텍스트의 대상 코드 내에 어떤 식별자들이 있는지에만 관심이 있고, 각 식별자에 어떤 값이 할당될 것인지는 관심이 없음. 따라서 변수를 호이스팅할때 변수명만 끌어올리고 할당 과정은 원래 자리에 그대로 둠.

b) 호이스팅 심화 (함수)

  • 함수를 정의하는 방식 세 가지

    // 함수 선언문
    function a(){ /* ... */ }
     a();
    
     // 익명함수 표현식
     var b = function (){ /* ... */ }
     b(); 
    
     // 기명 함수 표현식
     var c = function d(){ /* ... */ }
     c(); 
     d(); // 에러
     
  • 문제)

     console.log(sum(1, 2));
      console.log(multiply(3,4));
    
      function sum (a, b) {
          return a + b;
      }
      var multiply = function (a, b) {
          return a * b;
      }
    정답보기
    
      var sum = function (a, b) { // 함수선언문 전체를 끌어올림
            return a + b;
      }
      var multiply;
    
      console.log(sum(1, 2)); // 3
      console.log(multiply(3,4)); // multiply is not a function
    
      multiply = function (a, b){
          return a * b;
      }

    해설) 함수 선언문은 전체가 끌어올려지는 이유는 자바스크립트의 창시자 브랜든 아이크가 자바스크립트를 유연하고 배우기 쉬운 언어로 만들고자 했기 때문, 덕분에 함수를 선언한 위치와 무관하게 그 함수를 실행할 수 있게 되었지만, 이로 인해 더 많은 혼란 야기
    함수 표현식은 변수 선언부만 호이스팅, 함수 표현식은 함수를 다른 변수에 값으로써 '할당'한 것이기 때문.


2) 스코프, 스코프체인, outerEnvironmentReference

  • 스코프: 식별자에 대한 유효범위
  • 스코프 체인: 식별자의 유효범위를 안에서 바깥으로 차례로 검색해나가는 것, 이를 가능하게 하는 것이 LexicalEnvironment의 OuterEnvironmentReference임
  • OuterEnvironmentRecord: 현재 호출된 함수가 선언될 당시의 LexcialEnvironment를 참조

a) 스코프 체인

var a = 1;
var outer = function(){
  var inner = function(){
   	console.log(a); // 1) undefined
    var a = 3;
  }
  inner();
  console.log(a); // 2) 1
}
outer();
console.log(a); // 3) 1

b) 변수 은닉화

위의 코드에서 inner 스코프의 LexicalEnvironment에 a 식별자가 존재하므로 스코프체인 검색을 더 진해하지 않음. inner 함수 내부에서는 전역공간에서 선언한 동일한 이름의 a변수에는 접근할 수 없음. 이를 변수 은닉화 라고 함

c) 지역변수, 전역변수

profile
🙌꿈꾸는 프론트엔드 개발자 신은수입니당🙌

0개의 댓글