TIL-49 실행 컨텍스트

PRB·2021년 11월 7일
0

JavaScript

목록 보기
16/24
post-thumbnail

1. 실행컨텍스트 란 ?

실행컨텍스트를 알기전에 큐,스택을 알고가야한다.
스택은 a,b,c,d를 순서대로 넣었다면 d,c,b,a 로 나와야하고
큐는 a,b,c,d를 순서대로 넣었다면 a,b,c,d로 나와야한다.
실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.

콜 스택에 동일한 환경에 있는 코드들을 실행할때 필요한 환경 정보들을 모아 컨텍스트를 구성하고 이를 콜 스택에 쌓아 올려서 가장 위에 있는 컨텍스트와 관련된 코드를 실행하는 방식이다.

실행컨텍스트는 전역 공간에서 자동으로 생성되는 전역 컨텍스트와 eval함수, 함수실행에 의한 컨텍스트 등이 있다.
흔하게 컨텍스트를 구성하는 방법은 함수를 실행하는것


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

위 코드는 예시이다.
1. 자바스크립트 코드를 실행순간 전역 컨텍스트가 콜스택에 담긴다.
2. 한줄 씩 읽다가 outer 함수를 호출하마녀 자바스크립트 엔진은 outer에 대한 환경 정보를 수집해서 outer 실행컨텍스트를 생선한 후 콜스택에 담는다.
3. 콜 스택의 맨위에 outer 실행 컨텍스트가 놓인 상태에 되어서 outer 실행 컨텍스트와 관련된 코드인 outer 함수 내부의 코드를 순차적으로 실행한다.
4. outer코드를 읽다가 inner 함수의 실행 컨텍스트가 콜스택이 가장위에 담기면 outer 컨텍스트와 관련된 코드의 실행을 중단하고 inner 함수 내부의 코드를 순서대로 진행할 것이다.
5. inner 함수의 실행이 종료되면 inner 실행 컨텍스트가 콜 스택에서 제거된다.
6. 이런방식으로 쭉 실행하다가 전역공간에 더는 실행할 코드가 남아 있지 않아 전역컨텍스트도 제거되고, 콜스택에는 아무것도 남지않은 상태로 종료된다.

2. 실행컨텍스트의 수집정보

실행컨텍스트 객체는 활성화되는시점에 Variable Environment, Lexival Environment, ThisBinding의 세 가지 정보를 수집한다.

실행 컨텍스트를 생성하게 될때는 Variable Environment 과 Lexival Environment이 동일한 내용으로 구성되지만 Lexival Environment은 함수 실행 도중 변경되는 사항이 즉시 반영된다.
(Variable Environment는 초기값유지)

Variable Environment와 Lexival Environment의 내부는 environmentRecord와 outer-EnvironmentReference로 구성 되어있다.

environmentRecord

environmentRecord에는 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장된다. 컨텍스트를 구성하는 함수에 지정된 매개변수 식별자, 선언한 함수가 있을 경우 그 함수 자체, var로 선언된 변수의 식별자 등이 식별자에 해당한다.
컨텍스트 내부 전체를 처음부터 끝까지 쭉 훑어나가며 순서대로 수집한다.
그렇기때문에 자바스크립트 엔진은 이미 해당 환경에 속한 코드의 변수명들을 모두 알고있게 된다.

호이스팅이란?
'끌어올리다'라는 의미의 hoist에 ing를 붙여 만든 동명사로, 변수 정보를 수집하는 과정을 이해하기 쉬운 방법으로 대체한 가상의 개념이다.
(자바스크립트 엔진이 실제로 끌어올리지는 않디만 편의상 끌어올린 것으로 간주하자는 것)

// 호이스팅 전
function a (){
  var x = 1;        //수집 대상 1
  console.log(x)
  var x;            //수집 대상 2
  console.log(x)
  var 2;            //수집 대상 3
  console.log(x)
}
a()

environmentRecord는 현재 실행될 컨텍스트의 대상 코드 내에 어떤 식벽자들이 있는지에만 관심이 있고, 각 식별자에 어떤 값이 할당될 것인지는 관심이 없다.
-> 변수를 호이스팅할 때 변수명만 끌어올리고 할당 관정은 원래 자리에 둔다.

// 호이스팅 후
function a (){
  var x;          // 수집 대상 1의 변수 선언 부분
  var x;          // 수집 대상 2의 변수 선언 부분
  var x;          // 수집 대상 3의 변수 선언 부분
  
  x = 1;          // 수집 대상 1의 할당 부분
  console.log(x)
  console.log(x)
  x = 2;          // 수집 대상 3의 할당 부분
  console.log(x)
}
a()

실행해 보면 1,1,2가 나오게 된다.

함수 선언문과 함수 표현식의 차이

함수 선언문이란 ?

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

함수 표현식이란 ?

var multiply = function (a,b) {
return a * b;
}
// 호이스팅 전
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 sum (a,b) {
	return a + b;
}
var multiply;

console.log(sum(1,2));
console.log(multiply(3,4));

multiply = function (a,b) {  // 변수의 할당부는 원래 자리!
	return a * b
}

함수 선언문은 전체를 호이스팅하고 함수 표현식은 변수 선언 부만 호이스팅 했다.
바로 여기서 차이가 발생한다.
sum 함수는 선언 전에 호출해도 아무 문제 없이 실행된다.
이렇게 함수 선언문은 혼란을 줄 수 있기 때문에 상대적으로 함수 표현식이 안전하다.

3. 스코프, 스코프체인, outerEnvironmentReference

스코프란 식별자에 대한 유효범위 이다.
어떤 경계의 A의 외부에서 선언한 변수는 A의 외부뿐 아니라 A의 내부에서도 접근이 가능하지만, A의 내부에서 선언한 변수는 오직 A의 내부에서만 접근할 수 있다. 이러한 식별자의 유효범위를 안에서부부터 바깥영역으로 차례로 나가는 것을 스코프체인 이라고 한다.

profile
사용자 입장에서 사용자가 원하는 것을 개발하는 프론트엔드 개발자입니다.

0개의 댓글