
const x = 1;
// (1)
function counter() {
const x = 10;
const inner = function () { console.log(x); }; // (2)
return inner;
}
const innerFunc = outer(); // (3)
innerFunc(); // 10
클로저는 상태를 안전하게 변경하고 유지하기 위해 사용함.
즉, 상태를 안전하게 은닉하고 특정 함수에게만 상태 변경을 허용하기 위해 사용됨.
function createCounter () {
let num = 0;
return {
increase: () => { return ++num; },
decrease: () => { return num > 0 ? --num : 0 }
}
}
const counter = createCounter();
counter.increase(); // 1
counter.decrease(); // 0
// 직접접근 X
console.log(counter.num); // undefined
캡슐화: 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하고 조작할 수 있는 동작인 메서드를 하나로 묶는 것.
부적절한 접근으로 부터 객체의 상태 변경을 방지하고, 객체간의 결합도를 낮추는 효과가 있음.
const Person = (function() {
let _age = 0; // private
// 생성자 함수
function Person(name, age) {
this.name = name; // public
_age = age;
}
// 프로토타입 메서드
Person.prototype.sayHi = function () {
console.log(`Hi! My name is ${this.name}. I am ${_age}.`);
};
return Person;
}());
const me = new Person('Lee', 20);
me.sayHi(); // Hi! My name is Lee. I am 20.
console.log(me.name); // Lee
console.log(me._age); // undefined
const you = new Person('Kim', 30);
you.sayHi(); // Hi! My name is Kim. I am 30.
console.log(you.name); // Kim
console.log(you._age); // undefined
me.sayHi(); // Hi! My name is Lee. I am 30.
위 코드를 보면 여러개의 instance를 생성시 _age 변수의 상태가 유지되지 않는다. 이처럼 정보은닉을 완벽하게 지원하진 않음(단순 정보은닉의 경우 Class의 private을 사용하자)