: 함수가 선언될 때의 스코프를 기억하여, 함수가 생성된 이후에도 그 스코프에 접근할 수 있는 기능
클로저는 자바스크립트의 함수가 일급 객체라는 특성과 렉시컬 스코프의 조합으로 만들어 진다.
렉시컬 스코프(Lexical Scope): 함수를 어디서 선언했는지가 아닌 함수를 어디에 선언 하였는지에 따라 결정되는 것, 정적 스코프(Static scope)라 부르기도 함
let x = 1; // global
function first(){
var x = 10;
second();
}
function second(){
console.log(x);
}
first();
second();
// 결과 : 1 1
자바스크립트에서는 위와 같은 코드를 작성할 때 이미 실행 단계에세 코드들의 스코프를 결정한다.
렉시컬 스코프를 따르기 때문에 함수를 선언한 시점에서 상위 스코프가 결정됨.
=> 함수를 어디에서 호출하였는지는 스코프 결정에 아무런 의미를 주지 않는다.
second() 함수가 first() 함수 안에서 호출 된 것과 상관 없이 second() 함수는 global 범위에 선언 되어 있으므로, global 범위에 있는 변수 x의 값 1이 두 번 출력된 것이다.
function outerFunction(outerVariable){
return function innnerFunction(innerVariable){
console.log('Outer Variable:'+ outerVariable);
console.log('Inner Variable:'+ innerVariable);
};
}
const newFunction = outerFunction('outside');
newFunction('inside');
실행 흐름
1. outerFunction('outside') 호출
-> outerVariable은 'outside'로 설정
-> 리턴값: innerFunction
2. const newFunction = outerFunction('outside')
-> 이제 newFunction은 innerFunction(innerVariable)을 가리킴
-> innerFunction은 outerVariable이 무엇이었는지 기억함
3. newFunction('inside')호출
Outer Variable: outer
Inner variable: inside
클로저 동작 방식 :
=> JavaScript는 함수가 return으로 다른 함수를 반환할 경우, 그 내부에서 사용된 외부 변수(= 자유 변수) 들을 함께 기억함.
변수와 함수의 접근 범위를 제어하고 특정 데이터와 상태를 유지하기 위해 자주 활용 된다.
function createLogger(name){
return function(){
console.log(`Logger:${name}`);
};
}
const logger = createLogger('MyApp')';
setTimeout(logger,1000); // 1초 후에 'Logger: MyApp' 출력
모듈 패턴 구현
: 모듈 패턴은 특정 기능을 캡슐화하고, 외부에 공개하고자 하는 부분만 선택적으로 노출하여 코드의 응집력을 높이고, 유지보수성을 향상 시키는 패턴
-> 클로저를 활용하면 필요한 함수와 데이터만 외부로 노출함으로써 모듈 패턴을 쉽게 구현할 수 있다.
참고 및 출처:
메일메일- 클로저란?