JavaScript 실행 컨텍스트(execution context)와 호이스팅(hoisting)
: 실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체 입니다. 이를 위해서 스택(stack)과 큐(queue)라는 데이터 구조에 대해 알고 있어야 합니다. 동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성하고 이를 콜 스택에 쌓아올렸다가, 가장 위에 쌓여있는 컨텍스트와 관련 있는 코드들을 실행합니다.
STACK 구조
IN (a, b, c, d) -> OUT (d, c, b, a)
QUEUE 구조
IN (a, b, c, d) -> OUT (a, b, c, d)
- STACK 구조는 우물 같은 데이터 구조입니다. 저장한 데이터가 차곡차곡 쌓이면 꺼낼 때는 반대순서가 됩니다.
- QUEUE 구조는 파이프 같은 데이터 구조입니다. 저장한 데이터가 들어가는 순서대로 꺼낼 때도 그대로 빠져나옵니다.
호이스팅(hoisting)
: 호이스팅이란 선언 부분이 최상단으로 끌어올려지는 것을 의미합니다. 함수를 어디서 선언하든지 실행할 수 있도록 개발한 것이라 추정되나 오히려 혼란이 발생했습니다. 실제로 끌어올려지는 것은 아니고 그와 같은 원리라 보면 되겠습니다. 실행 컨텍스트의 선언된 변수나 함수(식별자)는 최상단으로 끌어올리고 할당은 원래 자리에서 할당하게 됩니다.
function a() {
console.log(b)
var b = 'bbb';
console.log(b);
function b () { }
console.log(b);
}
a();
- 원래 코드. error, 'bbb', b함수가 나올 것 같습니다.
function a() {
var b
function b () { }
console.log(b)
b = 'bbb';
console.log(b);
console.log(b);
}
a();
- 실행 후 호이스팅 적용된 진행순서. 함수와 변수가 최상위로 이동. 실제로는 b함수, 'bbb', 'bbb' 순으로 반환됩니다.
: 함수 선언문은 함수 안의 내용까지 전체 호이스팅하지만 함수 표현식은 변수 선언부만 호이스팅하고 값에 해당하는 할당부분은 마찬가지로 원래 위치에 유지됩니다. 함수 표현식과 선언식의 차이가 이부분입니다.
function a() {
console.log(b)
var b = 'bbb';
console.log(b);
var b = function () { } // 이부분만 함수 표현식으로 수정
console.log(b);
}
a();
- 원래 코드
function a() {
var b
console.log(b)
b = 'bbb';
console.log(b);
b = function () { } // 이부분만 함수 표현식으로 수정
console.log(b);
}
a();
- 실행 후 호이스팅 적용된 진행순서. undefined, 'bbb', b함수 순으로 반환됩니다.
다시 보는 스코프체인(Scope Chain)
: 함수가 중첩되어 있을 때 함수 내부에서 외부로 검색해 나가는 것을 스코프체인이라고 합니다. 이 때도 호이스팅이 적용됩니다.
var a = 1;
var outer = function () {
var inner = function () {
console.log(a);
var a = 3;
};
inner();
console.log(a);
};
outer();
console.log(a);
- 원래코드
var a = 1;
var outer
outer = function ()
outer();
{var inner
inner = function () {
var a
console.log(a);
a = 3;
};
inner();
console.log(a);
};
console.log(a);
- 실행 후 호이스팅 적용된 진행순서
- 첫번째로 변수 a에 1이 할당됩니다. outer가 선언되고 함수가 할당 됩니다.
- 그리고 하단의 함수 outer() 가 호출됩니다.
- outer 함수 안에 변수 inner가 선언 및 함수가 할당됩니다.
- 그리고 하단의 함수 inner() 가 호출됩니다.
- 선언된 변수 a가 inner함수 내 최상단으로 호이스팅 됩니다.
- 할당전 console.log로 undefined가 출력됩니다.
- 이후 a=3이 할당되지만 함수스코프로 inner함수 밖으로 벗어나지 못합니다.
- 그 다음 console.log(a)는 해당 outer 함수 내에 a를 찾을 수 없으므로 외부 전역변수 a의 1을 출력합니다.
- 마지막으로 console.log(a)도 동일하게 전역변수 a에 할당된 1을 출력합니다.
정리
- 실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체
- 식별자만 따로 분리해서 처리. 호이스팅이 발생한다.
- 호이스팅이란 실행 컨텍스트의 선언된 변수나 함수는 최상단으로 끌어올리고 할당은 원래 자리에서 하는 것
- 코드의 안전성을 위해 가급적 전역변수 사용을 최소화 할 것
- let, const 사용 등으로 스코프를 명확하게 할 것
참고
PoiemaWeb - 실행 컨텍스트와 자바스크립트의 동작 원리
'웹 > JavaScript' 카테고리의 다른 글
JavaScript 일급객체와 고차 함수 (0) | 2021.01.24 |
---|---|
JavaScript Closure (0) | 2021.01.18 |
JavaScript Scope chain과 Lexical scoping (0) | 2021.01.10 |
JavaScript Scope (0) | 2021.01.10 |
JavaScript Rest Parameter(나머지 매개변수) 와 Spread syntax(전개 연산자) (0) | 2021.01.10 |