내가 찾아가는 JavaScript_실행 컨텍스트(上)

Daniel Woo·2022년 4월 1일
0
post-thumbnail

들어가며

중요성
실행 컨텍스트(Execution Context)는 자바스크립트의 동작원리와 같다. 컴퓨터 언어의 동작 원리를 이해한다면 코드의 진행을 예측할 수 있다. 즉, 예측 가능한 코드를 작성할 수 있고, 버그를 최소화할 수 있는 것이다. 그렇게 때문에 조금은 어려웠지만 끝까지 학습하여 이해한 내용을 바탕으로 실행 컨텍스트의 개념을 정리해보려고 한다. 내용은 『모던 자바스크립트 딥다이브』와 유튜브의 영상을 통해 정리하였다.

자바스크립트의 동작 원리인 실행 컨텍스트를 이해하면,
예측 가능하고 버그가 적은 코드를 작성할 수 있다.

관련 내용
실행 컨텍스트의 동작원리를 이해하는 과정에서 우리는 스코프, 바인딩 값 관리 방식, 호이스팅의 이유, 태스크 큐 및 비동기 처리등에 대해 관련지어 이해할 수 있을 것이다. 그 동안 그냥 그런줄로만 알았던 JS만의 특징에 대해 조금 더 원리적인 이해가 가능하다는 점에서 조금 복잡하더라도 차근히 이해해나가보도록 하자.

소스코드의 종류

아래 네 가지 타입의 소스코드는 각각의 실행 컨텍스트를 생성한다.

4가지 타입의 소스코드

전역 코드
전역에서 존재하는 코드를 담은 코드의 무리이다. 다른 타입에 포함되어 있지 않은, 오로지 전역에 존재하는 코드를 말한다.

함수 코드
함수 내부에 존재하는 코드 뭉치이다.

eval 코드
MDN에 의하면 eval은 '문자코드로 표현된 코드를 실행하는 함수'이다.

JavaScript 개발에 참여하고 JSON을 보급한 미국의 프로그래머 Douglas Crockford가 'eval() is evil'라고 말할만큼 사용이 권장되지 않는 함수 형태라고 한다. 특수한 경우에서만 사용되기 때문에 '이런 타입의 소스코드가 있구나~'하고 가볍게 넘어가면 될 것 같다.

모듈 코드
자바스크립트에서 모듈이란 관련된 코드를 담고 있는 독립 파일을 말한다. 모듈이 나타내는 의미와 같이 모듈 형태를 지닌 특정 코드 블럭의 소스코드 타입이다.

소스코드의 평가와 실행

소스코드의 평가

실행 컨텍스트 생성
자바스크립트의 엔진은 소스코드를 마주했을 때 우선 해당 소스코드 타입에 맞는 실행 컨텍스트를 생성한다. 이후 위에서 부터 아래로 코드를 읽는데, 특이한 점은 코드를 바로 실행하지 않는다는 것이다. 대신에 해당 실행 컨텍스트에 있는 모든 변수와 함수 등의 선언문을 파악한다.

예를 들어, 다음과 같은 코드가 있다면, 전역 실행 컨텍스트에서 '코드'라는 변수의 식별자를 캐치하고 실행 컨텍스트의 스코프에 등록한다. 이 때 변수일 경우 값은 암묵적으로 undefined 로 초기화 된다. 코드가 모두 평가된 이후 코드 실행이 진행된다.

var 코드 = 'code'
console.log(코드)

앞으로 진행되는 실행 컨텍스트의 동작원리 이해를 위해 다음 코드를 기준으로 생각해보자.

var 변수_1 = 5;
const 변수_2 = -1;

function 전역함수_a(인자_a){
	var 변수_1 = 3; 
	const 변수_2 = 5;
    
	function 지역함수_b(인자_b){
    	const 변수_3 = 0;
        console.log(인자_a + 인자_b + 변수_1 + 변수_2 + 변수_3);
    }
    
    지역함수_b(5);
}

전역함수_a(27);

소스코드의 실행

1. 식별자를 스코프에 등록
최초 JS엔진에 의해 평가된 식별자는 이후에 자세히 알아볼 렉시컬 환경(Lexical Environment)에서 스코프에 등록이 된다. 스코프에 등록이 된 식별자는 값이 초기화된 상태이고, 코드가 실행함에 따라 값을 업데이트 한다.

예를 들어, 위의 전역 실행 컨텍스트에서 변수_1, 변수_2, 함수_a가 식별자로 등록이 되었고 변수는 undefined로 값이 초기화 된 상태이다. 코드 평가가 끝났다면 코드가 순차적으로 실행되고, 변수_1 = 5; , 변수_2 = -1; 을 통해 렉시컬 환경에 등록된 해당 스코프 값이 업데이트 된다.

환경 레코드의 변화

선언 환경 레코드(평가) 				선언 환경 레코드(실행)
변수_1    | undefined	 	==> 	변수_1    |   5
변수_2    | undefined				변수_2    |   2 
전역함수_a | < function object >     전역함수_a | < function object > 

2. 스코프 체인 형성
스코프 체인이란 등록된 변수나 함수 등이 있는 영역까지 내부에서 외부로 스코프를 연결시키는 것을 말한다. 이를 통해 하위 함수가 상위 함수의 값을 이용할 수 있거나 전역 값을 참조할 수 있는 것이다.

3. 실행중인 코드의 순서 변경
소스 코드는 실행 컨텍스트 스택에서 실행 순서에 따라 처리된다. 하나의 실행 컨텍스트가 등록되었다고 그 실행 컨테스트가 끝날 때 까지 다른 실행 컨텍스트가 실행되지 않는 것이 아니다. 전역에서 함수, 외부 함수에서 내부 함수처럼 내부에 속할 수록 실행 컨텍스트 스택 가장 위에 쌓여 우선 순위가 높은 실행 컨텍스트가 된다. 우선 순위가 높은 가장 위의 실행 컨텍스트는 실행 중인 실행 컨텍스트(Running Execution Context)가 되어 작업이 진행된다.

이렇게 실행 단위가 세부적인 작업 부터 우선적으로 마치는 실행 컨텍스트 스택의 특성 덕분에 자바스크립트는 싱글 쓰레드 언어임에도 불구하고 마치 멀티 쓰레드인 것처럼 동작의 빠른 처리가 가능한 것이다.

저장 공간 → 렉시컬 환경, 식별자 스코프
실행 순서 → 실행 컨텍스트 스택(call stack)

평가와 실행 사이클

소스코드가 평가되고(선언문, 식별자) → 평가 결과는 실행 컨텍스트의 환경 레코드(Environment Record)에 저장 → 소스코드 실행(선언문 외)
→ 결과를 실행 컨텍스트의 환경 레코드에 반영(업데이트)


참고 자료

MDN 공식 문서 - eval() 함수
Free Code Camp - 모듈

다음 글 보기 😉

👉 내가 찾아가는 JavaScript_실행 컨텍스트(中)

profile
모두가행복한세상을만들고싶은사람

0개의 댓글