일급객체
다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체
- 변수에 할당(assignment)할 수 있습니다.
- 다른 함수를 인자(argument)로 전달 받습니다.
- 다른 함수의 결과로서 리턴될 수 있습니다.
function outerFunc() {
let x = 10;
function innerFunc() {
console.log(x);
}
innerFunc();
}
outerFunc(); // 10
✔️ 스코프는 함수를 호출할 때가 아니라 함수를 어디에 선언하였는지에 따라 결정 됩니다. 이를 렉시컬 스코핑(Lexical scoping)이라 합니다.
실행컨텍스트의 스코프 체인을 자바스크립트 엔진이 검색하였기에 내부함수 innerFunc가 외부함수 outerFunc의 변수 x에 접근할 수 있습니다.
let x = 20;
function outerFunc() {
let x = 10;
let innerFunc = function () {
console.log(x);
};
return innerFunc;
}
/*
함수 outerFunc를 호출하면 내부 함수 innerFunc가 반환됩니다.
그리고 함수 outerFunc의 실행 컨텍스트는 소멸합니다.
*/
let inner = outerFunc();
inner(); // 10
console.log(x); // 20
함수 outerFunc는 내부함수 innerFunc를 반환하고 종료됐다. 하지만 위 코드는 x의 값이 10을 반환한다. 실행컨텍스트 스택에서 제거된 함수 outerFunc의 지역변수 x에 접근을 한것입니다.
자신을 포함하고 있는 외부함수보다 내부함수가 더 오래 유지되는 경우, 외부 함수 밖에서 내부함수가 호출되더라도 외부함수의 지역 변수에 접근할 수 있는데 이러한 함수를 클로저(Closure)라고 부릅니다.
클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수를 말합니다.
클로저는 자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수라고 말할 수 있습니다.
클로저 정의
함수는 자신의 선언된 위치의 렉시컬 환경을 기억합니다.
렉시컬 환경은 함수가 선언된 위치의 스코프입니다.
외부함수가 종료되었음에도 내부함수가 외부함수의 식별자를 참조 할 수 있기 때문에 클로저라고 합니다.
실용적인 클로저
자바스크립트에서는 클로저를 실용적으로 활용하기 위해서
위 두가지 조건을 제외한 나머지는 가비지컬렉션 대상이 됩니다.
클로저는 자신이 선언된 렉시컬 환경을 기억(참조가능)하기 때문에 불필요한 식별자를 참조하는 것을 피하기 위해서 사용합니다.
https://ko.javascript.info/closure
https://poiemaweb.com/js-closure#2-%ED%81%B4%EB%A1%9C%EC%A0%80%EC%9D%98-%ED%99%9C%EC%9A%A9