클로저는 함수와 그 함수가 접근할 수 있는 변수의 조합
MDN의 정의에 따르면
"클로저는 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다."
const x = 1;
function outerFunc() {
const x = 10;
function innerFunc() {
console.log(x); // 10
}
innerFunc();
}
outerFunc();
다음은 outerFunc
함수 내부에서 중첩함수 innerFunc
가 정의되고 호출되었다. 이때 외부함수outerFunc
는 innerFunc
의 상위 스코프이기 때문에 innerFunc
내부에서 자신을 포함하고 있ㄴ는 외부함수 outerFunc
에 접근할 수있다.
const x = 1;
function outerFunc() {
const x = 10;
innerFunc();
}
function innerFunc() {
console.log(x); // 1
}
outerFunc();
innerFunc
함수가 outerFunc
함수의 내부에서 정의된 중첩 함수가 아니면 outerFunc
함수의 변수에 접근할 수 없다.
이 현상은 자바스크립트가 렉시컬 스코프를 따르는 프로그래밍 언어이기 때문이다.
실행 컨텍스트(execution context)는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체로, 자바스크립트의 동적 언어로서의 성격을 가장 잘 파악할 수 있는 개념이다.
실행 컨텍스트는 자바스크립트 코드가 실행되는 환경이다. 모든 JavaScript 코드는 실행 컨텍스트 내부에서 실행된다고 생각하면 된다.
즉 함수가 실행되면 함수 실행에 해당하는 실행 컨텍스트
가 생성되고, 자바스크립트 엔진에 있는 콜 스택에 차곡차곡 쌓인다.
그리고 가장 위에 쌓여있는 컨텍스트와 관련 있는 코드를 실행하면서(LIFO), 전체 코드의 환경과 순서를 보장하게 된다.
실행 컨텍스트는 식별자(변수, 함수, 클래스 등의 이름)를 등록하고 관리하는 스코프와 코드 실행 순서 관리를 구현한 내부 매커니즘으로, 실행 컨텍스트는 곧 자바스크립트의 핵심 원리다.
자바스크립트 엔진은 함수를 어디서 호출했는지가 아니라 함수를 어디에 정의했는지에 따라 상위 스코프를 결정하는데 이를 렉시컬 스코프(정적 스코프)라고 한다.
렉시컬 환경의 "외부 렉시컬 환경에 대한 참조"에 저장할 참조값, 즉 상위 스코프에 대한 참조는 함수 정의가 평가되는 시점에 함수가 정의된 환경(위치)에 의해 결정된다.