[JS] 실행 컨텍스트(코어 자바스크립트)

mokyoungg·2020년 8월 1일
0

코어자바스크립트

목록 보기
2/3

모든 내용의 출처는 코어 자바스크립트입니다.

http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&linkClass=&barcode=9791158391720


  • 실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체.
  • 자바스크립트는 어떤 실행 컨텍스트가 활성화되는 시점에 선언된 변수를 위로 끌어올리고(호이스팅)
    외부 환경 정보를 구성하고, this 값을 설정하는 등의 동작을 수행한다.

1. 실행 컨텍스트란?

스택(Stack)

  • 출입구가 하나뿐인 깊은 우물 같은 데이터 구조.
  • a,b,c 순서로 저장했다면, 꺼낼 때는 c,b,a 순서로 꺼낸다.
  • 스택에는 한계가 있으며, 스택이 넘칠 때 에러를 던진다.

  • 양쪽이 모두 열려있는 파이프 같은 데이터 구조.
  • 일반적으로 한쪽은 입력만, 다른 한쪽은 출력만을 담당하는 구조.
  • a,b,c 순서로 저장했다면, 꺼낼 때는 a,b,c 순서로 꺼낸다.
  • 실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.
  • 동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성하고,
    이를 콜 스택(call stack)에 쌓아올렸다가, 가장 위에 쌓여있는 컨텍스트와 관련있는
    코드들을 실행하는 식으로 전체 코드의 환경과 순서를 보장한다.
  • 어느 실행 컨텍스트가 콜 스택의 맨 위에 쌓이는 순간이 곧 현재 실행할 코드에 관여하게 되는 시점.
  • 자바스크립트 엔진은 해당 컨텍스트에 관련된 코드들을 실행하는 데
    필요한 환경 정보들을 수집해서 실행 컨텍스트 객체에 저장

필요한 환경 정보는 다음과 같다.

VaribleEnvironment

  • 현재 컨텍스트 내의 식별자들에 대한 정보
  • 외부 환경 정보 선언 시점의 LexicalEnvironment의 스냅샷
  • 변경 사항은 반영되지 않음

LexicalEnvironment

  • 변경 사항이 실시간으로 반영됨.

ThisBinding

  • this 식별자가 바라봐야 할 대상 객체

콜 스택이란?
컴퓨터 프로그램에서 실행 중인 서브루틴에 관한 정보를 저장하는 스택 자료구조이다.
그냥 줄여서 스택이라고도 한다. 콜 스택을 사용하는 주된 이유는 실행 중인 서브루틴의 실행이 끝났을 때,
제어를 반환할 지점을 보관하기 위해서이다. 실행 중인 서브루틴은, 호출되어서 그 실행이 아직 완료되지는 않았지만,
완료후에는 호출된 지점으로 제어를 넘겨야 한다. 서브루틴의 이러한 실행은 여러 단계로 중첩될 수도 있는데,
다른 호출에 의해 또 다른 서브루틴으로 넘어가버리거나, 재귀같은 특별한 경우가 있다.
이러한 중첩의 특성 때문에 스택 자료 구조를 사용하는 것이다. 메모리 주소가 서브루틴이 끝날 때 반환 주소를 확인하도록 하고,
이를 위해 서브루틴 호출시 콜 스택에 반환 주소를 제일 먼저 집어 넣는다

출처 : 위키백과


2. VariableEnvironment

  • 최초 실행 시의 스냅샷을 유지.
  • 실행 컨텍스트를 생성할 때 Va..에 정보를 먼저 담은 후, 이를 그대로 복사하여 LexicalEnvironment를 만듬.
  • 이후에는 잘 사용하지 않음.

3. LexicalEnvironment

  • 컨텍스트를 구성하는 환경 정보들을 모아놓은 것

3-1. environmentRecord와 호이스팅

  • 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장.
  • 매개변수의 이름, 함수 선언, 변수명 등이 담김
  • 컨텍스트 내부 전체를 처음부터 끝까지 순서대로 수집한다.
  • 코드가 실행되기 전임에도, 자바스크립트 엔진은 해당 환경에 속한 코드의 변수명을 알고 있다.

호이스팅

  • '끌어올리다'
  • 변수 정보를 수집하는 과정을 더욱 이해하기 쉬운 방법으로 대체한 가상의 개념
  • 변수는 선언부와 할당부를나누어 선언부만 끌어올리는 반면 함수 선언은 함수 전체를 끌어올림.

함수 선언문과 함수 표현식

  • 함수를 새롭게 정의할 때 쓰이는 방식.
  • 함수 선언문의 경우 반드시 함수명이 정의돼 있어야 하는 반면, 함수 표현식은 없어도 된다.
  • 함수를 다른 변수에 값으로서 '할당'한 것이 함수 표현식

함수 선언문 : function 정의부만 존재, 별도의 할당 명령이 없는 것
함수 표현식 : 정의한 function을 별도의 변수에 할당하는 것을 말함.

//함수 선언문, 함수명 a가 곧 변수명
function a() {}
a(); // 실행

//(익명) 함수 표현식, 변수명 b가 곧 함수명
var b = function() {}
b(); // 실행

//기명 함수 표현식, 변수명은 c, 함수명은 d
var c = function d() {}
d(); // 에러

호이스팅에선 함수 선언문과 함수 표현식

  • 함수 선언문은 전체를 호이스팅
  • 함수 표현식은 변수 선언문만 호이스팅
  • 함수 선언문을 사용한느 것은 혼란을 일으키는 원인이 되기도 한다.
  • '선언한 후에야 호출할 수 있다'라는 편이 자연스럽다.

'###' is not a function

코드를 치면서 몇번 겪어본 에러 메시지이다.
특히 map을 사용할 때 많이 본 것 같다.
map의 대상이 배열이 아닌 경우도 있었지만,
지금 기억해보면 아무런 문제가 없는데 저런 메시지가 떠서 당황했던적이 있다.
호이스팅과 관련된 문제였구나...


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

  • 스코프란 식별자에 대한 유효 범위.
  • '식별자의 유효범위'를 안에서부터 바깥으로 차례로 검색해나가는 것을 스코프 체인.
  • 이를 가능하게 하는 것이 outerEnvironmentReference

스코프체인

  • outerEn... 은 현재 호출된 함수가 선언될 당시의 Lexical..를 참조한다.
  • 선언 시점을 계속 찾아 올라가면 마지막엔 전역 컨텐스트의 Lex..가 있음.
  • 가장 가까운 요소부터 차례대로만 접근할 수 있고 다른 순서로 접근하는 것은 불가능
  • 여러 스코프에서 동일한 식별자를 선언한 경우에는
    무조건 스코프 체인 상에서 가장 먼저 발견된 식별자에만 접근 가능

전역변수와 지역변수

전역 변수 : 전역 공간에서 선언한 변수
지역 변수 : 함수 내부에서 선언한 변수

  • 코드의 안전성을 위해 전역변수 사용을 최소화하는 것이 좋음.

profile
생경하다.

0개의 댓글