이 글은 코어자바스크립트 특강 내용을 정리한 글입니다.
클로저 정의 : 함수와 그 함수가 선언될 당시의 LexicalEnvironment의 조합
실행 컨텍스트 A의 내부에 함수B를 선언한 상황에서
실행 컨텍스트 A와 내부 함수 B가 콤비가 되어 무언가를 한다.
컨텍스트 A에서 선언한 변수를 내부함수 B에서 접근할 경우에만 발생하는 특수한 현상이 있는데 이것이 클로저의 특징이다.
(B의 outerEnvironmentReference는 A의 environmentRecord를 참조)
컨텍스트 A에서 선언한 변수 a를 참조하는 내부함수 B를 A의 외부로 전달할 경우,
A가 종료된 이후에도 A의 변수 a가 사라지지 않는 현상
쉽게 말해, 내부함수 B 를 외부에서 할당하면 컨텍스트 A 의 지역변수가 사리지지 않는 현상!
❗️이런 특수한 현상을 이용해서
함수가 종료된 이후에도 사라지지 않는 지역변수를 만들 수 있다.
var outer = function() {
var a = 1;
var inner = function() {
console.log(++a);
};
inner();
}
outer();
전역 컨텍스트 - outter 컨텍스트 - inner 컨텍스트 순으로 쌓였다가 해제된다.
outer2
클로저로 사용var outer = function() {
var a = 1;
var inner = function() {
return ++a;
};
return inner;
}
var outer2 = outer();
console.log(outer2()); // 실행결과 2
outer
함수의 리턴값이 inner
함수로 하고 외부에 outer2
라는 변수에 outer
함수의 내부함수인 inner
할당하면 클로저가 동작된다.
위 코드의 콜스택을 보면 outer는 해제되지 않고 살아 남아 있다.
하나의 함수의 지역변수로 서로 다른 클로저를 사용하면 마치 클래스와 객체처럼 서로 다른 프로퍼티처럼 사용할 수 있다.
또한 함수 내부의 변수
name
과age
를 getter와 setter로만 접근 할 수 있기 때문에 프라이빗 하게 안전하게 사용할 수 있다.
function showMike(age) {
var name = 'mike';
return {
get name() {
return name;
},
set name(_name) {
throw Error('read only');
},
get age() {
return age;
},
set age(_age) {
age += _age;
},
};
}
var dctorMike = showMike(42);
var policeMike = showMike(31);
// dctorMike
console.log(dctorMike.name);
console.log(dctorMike.age);
// policeMike
console.log(policeMike.name);
console.log(policeMike.age);