[JS] 자바스크립트 실행 컨텍스트

자바스크립트 엔진

자바스크립트 엔진 = 자바스크립트를 읽고 동작시키는 프로그램

기존에 사용하던건 크롬 브라우저의 V8

기존의 V8을 발전시켜 다른 환경에서도 사용할 수 있게 만들어 준것이 node.js고, 이걸 자바스크립트 런타임이라고 함

 

자바스크립트 실행 순서

1) 실행 컨텍스트 생성

2) 전역 컨텍스트 평가 스택에 추가

3) 함수 컨텍스트 평가 스택에 추가

4) 내부 함수까지 평가를 마쳤다면, 이벤트 루프에 밀어넣고 큐에 추가

5) 동기/비동기 나눠서 수행 후 일이 끝났다면 스택을 하나씩 걷어낸다

6) 스택을 모두 걷어내면 끝!

 

실행되는 방법

1) 실행컨텍스트 = 자바스크립트를 실행하는 전체적인 맥락

  • 자바스크립트 엔진은 전역 스코프를 제일 먼저 평가함
  • 콜스택에 가장 먼저 전역 스코프가 쌓인다
    • 선언부 확인: 변수, 함수 선언부가 저장됨 (호이스팅 되는 이유, 엔진이 어떤것이 선언돼있는지를 먼저 확인함)
    • 참고: var / let, const 는 서로 다른 공간에서 관리됨 (선언부로 먼저 콜스택에 있는 건 마찬가지, 그래서 var는 초기화되지 않은 상태에서 사용하면 undefined 가 들어가있고, let+const는 reference error 발생

 

2) 전역컨텍스트를 순차적으로 실행

  • 하나씩 할당 시작
  • 할당하는 부분에 도달하기 전에 참조(사용)을 먼저하면 레퍼런스 오류 혹은 undefined가 나오는데 이렇게 선언-할당 사이에 생긴 영역을 TDZ 라고 함

 

3) 그러다가 함수 내용을 할당할 때 함수 스코프 안에서 전역객체를 평가한 것처럼 선언부 먼저 -> 함수 컨텍스트 의 맥락으로 다시 평가함 (함수 컨텍스트가 콜스택에 쌓임)

  • 상위 스코프에 접근할 수 있도록 함수를 호출한 outer 또한 저장해둔다

 

4) 이렇게 실행되면 함수 내부를 평가하고 또 실행되면 다음 함수 내부를 평가하게되면서 콜스택에 차곡차곡 실행 컨텍스트가 쌓이는 것

  • 이 과정에서 this 바인딩이 일어남
  • 일반함수가 아닌 특정 레퍼런스 타입 객체에서 메서드가 호출되는 경우 this가 해당 객체로 바인딩된다
  • 화살표함수는 let, const에 함수를 할당할 때 사용
    • 따라서 this가 없고, 상위 스코프에서 찾게 됨

 

console.log에서 console은 어디있을까??

전역 컨텍스트에 있다. 우리가 작성하진 않지만 기본적으로 사용할 수 있는 javascript 개발 패키지가 전역 컨텍스트에 들어있다. 이를 전역변수, 전역객체, 빌트인 메서드, 내장함수 등이다.

 

5) 평가 후 실행 -> 함수 내부가 모두 실행되면 콜스택에서 pop -> 상위 컨텍스트에 남은 부분이 있다면 실행하고, 없으면 pop

  • 이를 반복하면서 전역까지 pop되면서 실행 컨텍스트가 비워진다

 

이벤트 루프

비동기 함수는 실행시키면 콜스택에서 pop -> loop 속으로 들어간다 (큐에 비동기 태스크 추가, web api 등)

그리고 나머지 동기함수를 실행시키면서 pop하는 건 그대로,

이벤트 루프가 다시 비동기함수를 콜스택으로 넣어준다

 

  • 콜스택: 싱글스레드, 한번에 하나만 처리함
  • 이벤트루프의 web api: 멀티스레드 (워커 스레드)

 

 

클로저 (closure)

자바스크립트의 함수가 본인이 선언된 환경(Lexical, 외부함수의 환경)을 기억하는 것

실행컨텍스트가 pop됐다하더라도 가비지컬렉터가 지우기 전까지 선언된 값을 지우지 않는다

그래서 함수가 실행됐던 환경이 pop되더라도 저장공간 안에 남아있어서 참조해올 수 있다