실행 컨텍스트와 CallStack

실행컨텍스트란?

실행 컨텍스트란 동일한 환경에서 돌아가는 코드가 실행될때 필요한 모든 것들이 구성되어있는 하나의 객체입니다. 이러한 실행컨텍스트는 함수로나 전역변수등으로 구성될 수 있습니다.
예를 들어 보면 박스에 피자가 배달되어 왔다고 합시다. 해당 박스에는 피자와 수저등 피자를 먹는데 필요한 모든 것들이 들어 있습니다. 여기서 박스안에 있는 모든것들이 실행컨텍스트 이고 피자는 자바스크립트 코드, 나머지 환경들은 수저등으로 해석할 수 있습니다.

전역 컨텍스트

전역 컨텍스트는 정확하게 단하나 입니다. 항상 가장 기본 컨텍스트로 존재합니다.최상위 코드가 실행되는 곳 입니다.

  • 최상위 코드란 어떠한 함수에도 들어있지 않는 코드입니다.
  • 함수내부 함수는 함수가 호출 될 때에만 실행됩니다.

코드의 실행순서


코드가 막 컴파일을 마치고 기계어로 변환되어 실행됩니다.

  1. 가장 먼저 최상위 코드가 실행되는 전역 실행 컨텍스트가 생성됩니다.
  2. 이후에 함수들과 콜백에 대기중인 것들도 실행되기 시작합니다. 각각의 모든 함수들에 대해서 실행 컨텍스트가 생성됩니다. ( 해당하는 코드를 실행시키기 위한 모든 필요정보들을 포함해서 실행 컨텍스트가 생성됨 )
  3. 이렇게 구성된 모든 실행 컨텍스트들은 CallStack 을 구성합니다.
  4. 모든 CallStack 구성이 완료되면 이벤트와 같이 CallBack에 대기중인 함수들도 실행이 가능하도록 자바스크립트 엔진은 대기중인 상태가 됩니다.

실행 컨텍스트의 구성

  1. 변수환경들이 들어있습니다.
    • 이러한 변수환경들에는 let, const, var 과 같은 선언방식과 함수들, 그리고 매개변수 객체등이 있습니다.
  2. 스코프 체인정보들이 있습니다.
    • 변수들에 대한 본래 선언된 위치 참조기능이 있어서 각 실행 컨텍스트 마다 해당하는 변수의 위치정보를 추적해 나갈 수 있습니다.
  3. this
    • this 키워드에 대한 정보도 기억되어 있습니다.

이러한 실행 컨텍스트의 구성은 실행 직전에 생성되어 집니다.

주의 해야할 점은 arrow-function에 의해 생성되어지는 실행컨텍스트 입니다.
arrow-function은 매개변수 객체와 this 라는 키워드에 대한 정보가 없이 실행컨텍스트가 구성됩니다.
하지만 이 arrow-function은 이러한 기능들을 가장 가까운 부모 함수의 실행컨텍스트에서 정보를 수집해서 사용할 수 있습니다.

Scope

변수가 선언된 정확한 위치에서 접근 가능한 범위 입니다. 함수 안에서 정의된 변수는 해당 함수안에서 접근 가능하며 블럭단위로 접근 가능한 변수가 달라집니다. 이러한 스코프는 변수의 범위와 동일하지 않습니다.

Scoping

프로그램의 변수들의 Scope 지정은 자바스크립트 엔진에 의해 구성되고 접근됩니다. 기본적으로 스코프 지정은 질문을 합니다.

  • 변수가 어디있는가?
  • 특정 변수에 접근가능한 곳과 그렇지 않은 곳은 어디인가?

Lexical Scoping

스코핑은 코드의 블럭들과 함수의 배치에 의해서 제어됩니다.

Scope Type

  1. Global Scope
    • 함수나 블럭들 제외한 공간입니다.
    • 여기에 선언된 변수들은 전역변수들로 프로그램 전반에 걸쳐 모든 곳에서 접근이 가능합니다.
  1. Function Scope

    • 모든 함수는 범위를 만듭니다. 그 함수 내에서 선언된 변수들은 해당 함수 내에서만 접근 가능합니다.
    • 이러한 스코프를 local Scope라고도 합니다.
  2. Block Scope (ES6)

    • 블럭이란 중괄호 사이에 있는 모든 것을 의미합니다.
    • 블럭내에서 선언된 변수는 해당 블럭 내에서만 접근 가능합니다.
    • 하지만 위와 같은 적용은 let, const로 선언을 할 경우에만 그렇다는 것입니다.
      ❗️ var 변수로 선언한다면 블럭 이외의 공간에서 접근이 가능해져버립니다. 따라서 var 선언은 함수 범위라고 말합니다.

ES5와 그전 기간동안에는 함수 스코프와 전역 스코프만 있었습니다. 따라서 블럭 스코프는 전혀 고려 대상이 아니였습니다. 이제 ES6부터 최소한 strict mode 에서는 함수 또한 블럭에서 선언된 경우 해당 블럭에서만 접근이 가능해졌습니다. strict mode 가 아니라면 블럭안에 정의된 함수일 지라도 var 처럼 함수 스코프로 접근이 가능해집니다. 따라서 항상 let, const 변수 선언 방식과 strict mode 로서 자바스크립트를 실행해야 합니다.

Scope Chain


변수들은 각 함수의 스코프에 존재합니다. 각 스코프들은 스코프안에 존재할 수도 있으며 중첩이 허용됩니다. 더구나 스코프들은 상위의 모든 스코프들에 대해 접근이 가능한데 가장 가까운 스코프 범위 부터 차례로 변수가 접근 가능한지 검색하며 올라갑니다. 이러한 과정들을 스코프 체인이라고 합니다.

이렇게 변수가 스코프 체인안에 있는지 검색하는 과정을 Variable Lookup이라고 합니다. 맨 하위 스코프에서 가장 최상위 스코프인 전역 스코프 까지 접근이 가능하지만 그 반대는 불가합니다.

올라가며 검색하는건 가능하지만 전역스코프에서 그아래 블럭 변수에 접근하는 것이 불가능합니다. 즉, 내려가는 변수 검색을 할수 없습니다. 측면의 같은 레벨의 블럭 변수도 마찬가지 입니다. 측면으로는 검색이 불가하며 올라가는 변수 검색만이 가능합니다.

예시에서 보듯이 하위 레벨로 갈수록 스코프 자체가 더 커집니다. 하위 레벨일 수록 가장 많은 부분의 변수 스코프를 가지기 때문입니다. 전역 스코프가 가장 스코프가 작고 하위레벨 일수록 스코프 범위가 큽니다.

💡 이러한 과정들은 모두 자바스크립트 런타임안에 자바스크립트 엔진이 하는 일들입니다.

❗️ 만약 같은 이름의 변수가 다른 스코프에 있는 경우 변수조회를 어떻게 할까요?

  • 이럴경우에는 스코프 체인시 가장 가까운 스코프에서 해당 변수이름을 가진 변수를 찾아서 조회합니다. 따라서 다른 스코프에 같은 이름으로 변수를 선언해도 가장 가까운 스코프에서 해당 변수를 조회합니다.
profile
일상을 기록하는 삶을 사는 개발자 ✒️ #front_end 💻

0개의 댓글