코어 자바스크립트 02_실행 컨텍스트

eunseo·2021년 4월 6일
post-thumbnail

코어 자바스크립트 02_ 실행 컨텍스트

✔ 1-1 실행 컨텍스트란 ? ✍

  • 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.
  • ES6에서는 블록{}과 함수를 통해 실행 컨텍스트를 구성한다.
  • 스택구조로 실행된다.
  • 활성화된 실행 컨텍스트의 수집 정보 : VariableEnvironment, LexicalEnvironment, ThisBinding

✔ 1-2 VariableEnvironment✨

  • VariableEnvironment에 담기는 내용은 LexicalEnvironmet와 같지만 최초 실행 시의 스냅샷을 유지한다는 점이 다르다.

✔ 1-3 LexicalEnvironment✨

  • 현재 컨텍스트의 내부에는 A,B 식별자들이 있고(EnvironmetRecord) 그 외부 정보는 D를 참조하도록 구성됨. (OuterEnvironmentRefrence)

    EnvironmetRecord : 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장(호이스팅)

    OuterEnvironmetRefrence : 바로 직전 컨텍스트의 LexicalEnvironmet 정보를 참조함.

◽ 1-3-1 호이스팅

  • EnvironmentRecord는 현재 실행될 컨텍스트의 대상 코드 내에 어떤 식별자들이 있는지에만 관심이 있고, 각 식별자에 어떤 값이 할당될 것인지는 관심이 없다.
    💥 따라서 변수를 호이스팅 할 때 변수명만 끌어올리고 할당 과정은 원래 자리에 그대로 남김
function a() {
  var x=1;
  console.log(x);
  var x;
  console.log(x);
  var x=2;
  console.log(x);
}

(1) 1, (2) undefined, (3) 2 로 출력 될까? ❌

code hoisting

function a(){
  var x;
  var x;
  var x;
  
  x=1;
  console.log(x);
  console.log(x);
  x=2;
  console.log(x);

}

(1) 1, (2) 1, (3) 2 로 출력 된다.😁

◽ 1-3-1-1 함수 선언문 vs 함수 표현식

함수 선언문 : 전체를 호이스팅

function sum(a,b){
  return a+b;
}

함수 표현식 : 변수는 선언부만 끌어올린다 (var multiply;)

var multiply = function(a,b){
  return a*b;
}
console.log(sum(1,2));
console.log(multiply(3,4)); --- error 

function sum(a,b){
  return a+b;
}

var multiply = function(a,b){
  return a*b;
}
  • sum 함수는 선언 전에 호출해도 아무 문제 없이 실행
  • multiply 함수는 에러 발생

◽ 1-3-2 스코프체인, OuterEnvironmentReference

  • 스코프체인이란?
    - 식별자의 유효범위를 안에서부터 바깥으로 차례로 검색해나가는 것이다.
  • 스코프체인을 가능케 하는 것이 OuterEnvironmetReference이다.
  • OuterEnvironmentReference는 현재 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조한다.

스코프체인 과정

var a=1;
var outer = frunction(){
  var inner = function(){
    console.log(a);
    var a=3;
  };
  inner();
  console.log(a);
};
outer();
console.log(a);
1. 시작 : 전역 컨텍스트 활성화 **environmentRecord**{a,outer} 전역 컨텍스트는 선언 시점이 없으므로 **outerEnvironmetReference** 에 아무것도 담기지 않음. 
2. 전역 스코프에 있는 a에 1을 outer에 함수를 할당함. 
3. outer함수 호출 


[outer 실행 컨텍스트 활성화]
4. outer 실행 컨텍스트의 **environmetRecord**{inner}  
outer함수는 전역공간에 선언되었으므로 전역 컨텍스트의 LexicalEnvironmet를 참조복사함. ** outerEnvironmetReference**: {GLOBAL,{a,outer}}
5. outer 스코프에 있는 변수 inner에 함수 할당 
6. inner 함수 호출


[inner 실행 컨텍스트 활성화]
7. inner 실행 컨텍스트의 **environmetRecord**{a} 
8. inner함수는 outer 함수 내부에서 선언되었으므로 outer 함수의 LexicalEnvironmet를 참조 복사 **outerEnvironmetReference** : {outer,{inner}}
9. 식별자 a에 접근 
- 현재 활성화 상태인 inner 컨텍스트의 environmentRecord에서 a를 검색
a가 발견됬는데 아직 할당된 값 없으면 undefined 출력 
10. inner 스코프에 있는 변수 a에 3을 할당 
11. inner 함수 종료. inner 실행 컨텍스트가 콜 스택에서 제거 되고, 바로 아래의 outer 실행 컨텍스트가 다시 활성화.


[inner 함수 종료 => outer 함수 다시 활성화]
12. 식별자 a에 접근하고자 함 
- 현재 활성화된 outer 실행 컨텍스트의 environmetRecord에 a가 있는지 찾아보고 없으면, outerEnvironmetReference에 있는 바로 직전 컨텍스트의 LexicalEnvironmet에서 계속 검사. 전역 LexicalEnvironmet에 a가 있으니 1 반환
13. outer함수 종료

[outer함수 종료 => 전역 컨텍스트 활성화]
14. 코드 11번째줄 식벽자 a에 접근하고자 함 
- 현재 활성화된 environmentRecord에서 a를 검색 바로 a를 찾고 모든 코드의 실행 완료 

변수에 접근
1. 현재 컨텍스트의 LexicalEnvironmet를 탐색
2. 없다면 OuterEnvironment에 담긴 LexicalEnvironment 탐색
3. 전역 컨텍스트의 LexicalEnvironment까지 탐색해도 해당 변수 없다면 Undefined.

profile
backend developer

0개의 댓글