클로저
는 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다.
const x = 10;
function outer() {
const x = 100;
const inner = function () {
console.log(x);
};
return inner;
}
const innerFunc = outer();
innerFunc(); // 100
• outer 함수를 호출하면 outer 함수는 중첩 함수 inner를 반환하고 함수의 실행이 종료 (생명 주기를 마감)
• 그런데 코드를 실행해보면 출력되는 결과는 100이 나오면서 마치 지역 변수 x가 살아있는 것 처럼 동작
• 외부 함수보다 중첩 함수보다 더 오래 유지되는 경우(생명 주기), 중첩 함수는 이미 생명 주기가 종료한 외부함수의 변수를 참조 가능하며, 이러한 중첩 함수를 클로저라 부른다.
function foo() {
const x = 1;
const y = 2;
function bar() {
debugger;
console.log(x);
}
return bar;
}
const bar = foo();
bar();
• 자바스크립트의 모든 함수는 상위 스코프를 기억하므로 이론적으로 모든 함수는 클로저다.
• 그러나 일반적으로는 중첩 함수가 상위 스코프의 식별자를 참조하면서, 중첩 함수가 외부 함수보다 더 오래 유지되는 경우로 한정한다.
• 예시 2에서처럼 클로저에 의해 참조되는 상위 스코프의 변수를 자유 변수(free variable)라 한다.
• 클로저란 의미는 함수가 자유 변수에 닫혀있다라는 의미 또는 자유 변수에 묶여있는 함수라고 할 수 있다.
클로저는 상태(state)를 안전하게 변경하고 유지하기 위해 사용한다. 상태를 은닉하고 특정 함수에게만 상태 변경을 허용하기 위함
const increase = function () {
let num = 0;
return ++num;
};
console.log(increase()); // 1
console.log(increase()); // 1
console.log(increase()); // 1
/* 제대로 동작하지 않는 것을 확인할 수 있는데
그 이유는 increase를 호출할 때마다 0으로 num이 초기화 되기 때문 */
const increase = (function () {
let num = 0;
return function () {
return ++num;
};
})(); // 즉시 실행 함수
console.log(increase()); // 1
console.log(increase()); // 2
console.log(increase()); // 3
/* 즉시 실행함수가 실행되어 return 문에 반환한 함수(클로저)가
increase 변수에 할당된다. 클로저는 상위 스코프인 즉시 실행 함수의
렉시컬 환경을 기억하고 있어 num 변수를 참조, 변경 할 수 있다. */
캡슐화(encapsulation)는 프로퍼티와 메서드를 하나로 묶는 것을 말하며 특정 프로퍼티 혹은 메서드를 감추는 정보 은닉(information hiding)을 목적으로 사용되기도 한다.
정보 은닉은 필요한 정보만을 외부에 공배함으로써, 불필요한 접근을 막고 객체 간 의존도를 낮추는 효과가 있다.
객체지향 프로그래밍 언어에서는 클래스를 정의하고 접근 제한자(access modifier)를 선언하여 공개범위를 한정할 수 있다.
• Public : 모든 프로퍼티, 메서드 외부에서 참조 가능
• Private : 모든 프로퍼티, 메서드 외부에서 참조 불가