TIL

Jony·2024년 5월 8일

[TIL]

목록 보기
17/46
post-thumbnail

Javascript

VariableEnvironment, LexicalEnvironment의 개요

  • VE vs LE 이 두가지는 담기는 항목은 완벽하게 동일해요. 그러나, 스냅샷 유지여부는 다음과 같이 달라요.
    • VE : 스냅샷을 유지한다.

    • LE : 스냅샷을 유지하지 않는다.
      즉, 실시간으로 변경사항을 계속해서 반영

      결국, 실행 컨텍스트를 생성할 때, VE에 정보를 먼저 담은 다음, 이를 그대로 복사해서 LE를 만들고 이후에는 주로 LE를 활용한다.

  • 구성 요소(VE, LE 서로 같다.)
  1. VE, LE모두 동일하며, environmentRecord와 outerEnvironmentReference로 구성
  2. environmentRecord(=record)
    2-1) 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장된다.
    2-2) 함수에 지정된 매개변수 식별자, 함수자체, var로 선언된 변수 식별자 등
    2-3) outerEnvironmentReference(=outer)

LexicalEnvironment- environmentRocord(=record)와 호이스팅

  • 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장(수집)된다. 기록=record

  • 수집 대상 정보 : 함수에 지정된 매개변수 식별자, 함수 자체, var로 선언된 변수 식별자 등

  • 컨텍스트 내부를 처음부터 끝까지 순서대로 훑어가며 수집( 순서대로 수집될 뿐 코드가 실행되진 않는다.)


호이스팅

  • 변수정보 수집을 모두 마쳤더라도 아직 실행 컨텍스트가 관여할 코드는 실행 전의 상태

  1. 매개변수 및 변수는 선언부를 호이스팅한다
    • 매개변수 적용 시
      		//action point 1 : 매개변수 다시 쓰기(JS 엔진	은 똑같이 이해한다)
      		//action point 2 : 결과 예상하기
      		//action point 3 : hoisting 적용해본 후 결과를 다시 예상해보기
      		function a () {
      		var x = 1;
      		console.log(x);
      		var x;
      		console.log(x);
      		var x = 2;
      		console.log(x);
      		}
      		a(1);
      		```
    • 호이스팅 적용시
      //action point 1 : 매개변수 다시 쓰기(JS 엔진은 똑같이 이해한다)
      //action point 2 : 결과 예상하기
      //action point 3 : hoisting 적용해본 후 결과를 다시 예상해보기
      function a () {
      	var x;
      	var x;
      	var x;
      x = 1;
      	console.log(x);
      	console.log(x);
      	x = 2;
      	console.log(x);
      }
      a(1);```
  1. 함수 선언은 전체를 호이스팅한다.
    //action point 1 : 결과 값 예상해보기
    //action point 2 : hoisting 적용해본 후 결과를 다시 예상해보기
    function a () {
    var b; // 변수 선언부 호이스팅
    function b() { } // 함수 선언은 전체를 호이스팅
    	console.log(b);
    b = 'bbb'; // 변수의 할당부는 원래 자리에
    	console.log(b);
    	console.log(b);
    }
    a();```
  1. 함수 선언문, 함수 표현식

    // 함수 선언문. 함수명 a가 곧 변수명
    // function 정의부만 존재, 할당 명령이 없는 경우
    function a () { /* ... */ }
    a(); // 실행 ok
    // 함수 표현식. 정의한 function을 별도 변수에 할당하는 경우
    // (1) 익명함수표현식 : 변수명 b가 곧 변수명(일반적 case에요)
    var b = function () { /* ... */ }
    b(); // 실행 ok
    // (2) 기명 함수 표현식 : 변수명은 c, 함수명은 d
    // d()는 c() 안에서 재귀적으로 호출될 때만 사용 가능하므로 사용성에 대한 의문
    var c = function d () { /* ... */ } 
    c(); // 실행 ok
    d(); // 에러!```

    실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.
    - 그 객체 안에는 3가지가 존재한다.
    ✓ VariableEnvironment
    ✓ LexicalEnvironment
    ✓ ThisBindings
    - VE와 LE는 실행컨텍스트 생성 시점에 내용이 완전히 같고, 이후 스냅샷 유지 여부가 다르다.
    - LE는 다음 2가지 정보를 가지고 있다.
    ✓ record(=environmentRecord) ← 이 record의 수집과정이 hoisting
    ✓ outer(=outerEnvironmentReference)


LexicalEnvironment - 스코프, 스코프 체인, outerEnvironmentReference(=outer)

  • 스코프

    • 식별자에 대한 유효범위를 의미해요

    • 대부분 언어에서 존재, 당연하게도 JS에서도 존재

  • 스코프 체인

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

  • outer는 스코프 체인이 가능하도록 하는 것(=외부 환경 참조 정보)

  • 스코프 체인

  • outer는 현재 호출된 함수가 선언될 당시 의 LexicalEnvironment를 참조(=그 당시의 환경 정보를 저장)

  • 예)
    A함수 내부에 B함수 선언 → B함수 내부에 C함수 선언(Linked List)한 경우,타고 올라가다 보면 전역 컨텍스트의 LexicalEnvironment를 참조

  • 항상 outer는 오직 자신이 선언된 시점의 LexicalEnvironment를 참조하고 있으므로, 가장 가까운 요소부터 차례대로 접근 가능

  • 무조건 스코프 체인 상에서 가장 먼저 발견된 식별자에게만 접근이 가능

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

각각의 실행 컨텍스트는 LE 안에 record와 outer를 가지고 있고, outer 안에는 그 실행 컨텍스트가 선언될 당시의 LE정보가 들어있으니 scope chain에 의해 상위 컨텍스트의 record를 읽어올 수 있다.

profile
알면 알수록 모르는 코태계

0개의 댓글