함수
와 함수가 선언된 lexical environment
의 조합이다.lexical environment
에 대해 알아볼 필요가 있다.어디서
정의했는지에 따라 상위 스코프를 결정한다.외부 렉시컬 환경에 대한 참조
라는 프로퍼티에 저장할 참조 값이다.외부 렉시컬 환경에 대한 참조
는 함수 정의가 평가되는 시점에 결정되므로 -> 함수를 어디서
정의했는지에 따라 상위 스코프를 결정한다.외부 렉시컬 환경에 대한 참조
를 저장하는 장소[[Environment]]
에 외부 렉시컬 환경에 대한 참조
가 저장되는 시점은 함수가 정의된 스코프에서 실행 컨텍스트가 실행될 때이다.[[Environment]]
에 지금 실행 중인 실행 컨텍스트의 렉시컬 환경에 대한 참조가 저장된다.외부 렉시컬 환경 참조
프로퍼티에 함수 객체의 내부 슬롯 [[Environment]]
에 있던 값을 넣는다.foo()
에 중첩 함수 boo()
가 선언되고, 함수 foo()
는 boo()
를 리턴한다고 하자foo()
의 외부 스코프의 실행 컨텍스트가 실행될 때, 함수 foo()
객체가 생성된다.foo()
가 호출 되었을 때, 실행 컨택스트에 함수 foo()
의 실행 컨택스트가 올라온다.foo()
의 실행 컨택스트가 실행되면서, 함수 boo()
객체가 생성되고, 함수 boo()
객체의 내부 슬롯 [[Environment]]에 함수 foo()
의 렉시컬 환경의 참조가 저장된다.foo()
가 함수 boo()
를 리턴하면 실행컨택스트 스택에서 함수 foo()
의 실행 컨택스트가 빠진다. 따라서 함수 foo()
의 렉시컬 환경이 접근할 수 없다.boo()
를 담은 값이 함수 boo()
를 호출하면 실행컨택스트 스택에 함수 boo()
의 실행 컨택스트가 올라가고, 함수 boo()
객체의 내부 슬롯 [[Environment]]의 참조 값이, 함수 boo()
의 외부 렉시컬 환경 참조에 저장이 된다.boo()
에서는 함수 foo()
의 생존여부과 관계없이, 함수foo()
의 렉시컬 환경이 접근 가능해진다.이때 함수 boo()
를 클로저
라고 부른다.
단, 외부 스코프의 어떤 식별자로 참조하지 않을 경우는 클로저가 아니다.
const increase = function() {
let num = 0
return function() {
return ++num
}
}
console.log(increase()) // 1
console.log(increase()) // 2