ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Execution Context
    JS 2021. 8. 7. 17:00

    Context란?

    어떤 코드에 관여하는 코드 맥락상의 조건, 환경

     

    그럼 실행 콘텍스트 Execution Context란?

    동일한 조건,환경을 지니는 코드뭉치를/ 실행할 때 필요한 조건,환경정보

    여기서 말하는 동일한 환경을 지니는 코드뭉치는 함수 또는 전역공간 뿐.

     

    => 함수를 실행할 때 필요한 환경정보 !

     

    Variable Environment - 값 변경 불가(snapshot)

    Lexical Environment - 값 변경 가능

     

    [ Lexical Enviroment ]

    - environmentRecord (현재 컨텍스트의 식별자)

         : 현재 문맥의 식별자 정보를 수집해서 끌어올림  => Hoisting과 같음

    -outerEnvironmentReference (외부 컨텍스트의 식별자)

         : 현재 문맥에 관련있는 외부 식별자 정보를 담는다

     

    Execution Context가 실행되면,

    가장 먼저 environmentRecord로 현재 문맥의 식별자 정보를 수집해서 끌어올린다는 것을 기억하자!

    ( * 단, 할당된 값까지 끌어올리지는 않음)

     

    var a = 1;
    function outer() {
      console.log(a); // 1
      function inner() {
        console.log(a); // 2
    	var a = 3;
      }
      inner();//inner를 만났을때 그제야 inner의 실행 콘텍스트가 열리며 
    
      console.log(a); // 3
      // inner 실행이 끝났으니까 이걸 실행
    }
    outer(); //outer를 만났을때 그제야 outer의 실행 콘텍스트가 열리며
    console.log(a); // 4
    // outer 실행이 끝났으니까 이걸 실행
    
    // 이렇게 마지막에 들어온게 가장먼저 빠지는 구조를 stack이라고 한다
    
    // 실행에 대한 것을 관여하는 것을 call stack이라고 함
    
    /*
    현재 어떤 함수가 동작하고 있는지, 다음에 어떤 함수가 호출되어야 하는지 등을
    제어하는 자료구조
    */

    Call Stack 설명

     

    inner LexicalEnvironment
        environmentRecord (내부접근가능)
        outerEnvironmentReference(외부접근가능) - outer에 접근가능
    outer LexicalEnvironment
        environmentRecord (내부접근가능)
        outerEnvironmentReference(외부접근가능) - 전역에 접근가능
    전역 LexicalEnvironment     environmentRecord (내부접근가능)

    * 내부로는 접근할 수 없다. 접근가능한 방법이 없음. 참조하고 있는 대상X

    ex) inner에서 선언한 var a = 1; 을 outer나 전역에서는 불러올 수 없음.

    하지만 전역에서 선언한 var a = 1;은 outer나 inner에서 불러올 수 있다.(outer나 inner에서 a를 선언해버리지 않은 이상)

     

    - 그런데 만약

    전역으로 var a = 1; outer에서 var a = 2; 로 선언되어있는 상태에서

    inner에서 var a의 값을 불러오려고 하면 뭐가 출력될까?

    => outer에서 할당한 a = 2가 출력된다. 제일 가까운 것을 찾기 때문에!

    전역의 a값과 outer의 a값 둘 다 있지만, outer에서 a를 선언함으로써 전역으로의 a 접근을 막는다

     

     

    이 도표를 바탕으로 위의 코드블럭을 실행 순서대로 자세히 설명하면

    var a = 1;
    function outer() {
      // outer가 실행되면 제일 먼저 내부의 선언된 식별자를 찾아 끌어올림
      // 그래서 inner가 먼저 선언된 셈.
      console.log(a);
      // outer엔 a가 없으니 전역에서 a를 찾아서 1을 출력
    
      function inner(){ //inner가 실행됐으니 변수 a를 수집해 올려서 선언
        console.log(a); // 이미 선언되어있기 때문에 inner내부에서 a를 찾는다.
        //하지만 선언만 됐을 뿐, 값은 아직 할당되지 않았음! undefined 출력!!!!
        var a = 3;
        // 그러고 나서야 a에 3이라는 값을 할당한다
      }
    
      inner();
      // inner를 실행(execution 컨텍스트 활성화)
    
      // inner함수는 종료됨
      console.log(a); //inner에는 접근할 수 없음. outer에서 a를 찾는다
      // a가 없으니 전역으로 1을 출력한다
    }
    outer(); //outer 실행
    // 함수 outer종료
    
    console.log(a);
    // 전역으로 나가서 찾아온 1을 출력한다

     

    function inner(){ //inner가 실행됐으니 변수 a를 수집해 올려서 선언

    console.log(a); // 이미 선언되어있기 때문에 inner내부에서 a를 찾는다.

    //하지만 선언만 됐을 뿐, 값은 아직 할당되지 않았음! undefined 출력!!!!

    var a = 3;

    // 그러고 나서야 a에 3이라는 값을 할당한다

    }

     

    * 이부분을 주의하자.

    위로 끌어올리는 environment Record(=Hoisting)은 단순히 선언만 위에서 할 뿐, 할당은 아직 되지 않았다는 것을 잘 기억하자.

    선언은 되어있지만 값이 할당되어있지 않으니 undefined라고 나올 수 밖에.

    'JS' 카테고리의 다른 글

    callback  (0) 2021.08.10
    this  (0) 2021.08.09
    this  (0) 2021.08.08
    Data type  (0) 2021.08.06
    form - input 상관관계, event 막기  (0) 2021.08.06
Designed by Tistory.