JS를 공부하면서 가장 혼란스러웠던 내용 중 하나인 클로저와 렉시컬환경에 대해 알아보고자 한다.
JS의 실행 중인 함수, 코드 블록 {...}, 스크립트 전체 는 렉시컬 환경(Lexical Environment) 이라 불리는 내부 숨김 연관 객체를 갖는다.
렉시컬 환경 객체는 다음의 두 부분으로 구성된다.
코드를 보며 이해해보자.
let global = 'global' // #1
if (true) {
let inner = 'inner' // #2
}
function foo() { // #3
let bar = 'bar'
console.log(bar + '/' + global);
}
foo(); // #4, bar/global 출력
따라서 foo 함수가 호출되었을 때에는 다음과 같은 플로우로 진행된다.
클로저란 외부 변수를 기억하고 이 외부 변수에 접근할 수 있는 함수를 의미한다.
자바 스크립트의 함수는 생성될 당시의 환경을 기억하고 저장하며 이를 통해 외부 렉시컬 환경에 대한 참조가 가능하므로, 모든 함수가 클로저라고 할 수 있다.
간단하게는 다음과 같은 방식으로 쓰일 수 있다.
function logger(header) {
return function(message) {
console.log(`${header} : ${message}`);
}
}
const orderLogger = logger('API'); // #1
const productLogger = logger('Product'); // #2
orderLogger('message'); // API : message
productLogger('message'); // Product : message