(function () {
var a = 'a';
})();
console.log(a); // a is not defined
직접적으로 변경되면 안 되는 변수에 대한 접근을 막는 것
자바스크립트에서 일반적인 객체지향 프로그래밍 방식으로 prototype를 사용하는데 객체 안에서 사용할 속성을 생성할 때 this 키워드를 사용하게 됩니다.
하지만 이러한 Prototype을 통한 객체를 만들 때의 주요한 문제가 하나 있습니다. 바로 개인 변수(Private variables)에 대한 접근 권한 문제입니다.
function Hello(name) {
this._name = name;
}
Hello.prototype.say = function() {
console.log('Hello, ' + this._name);
}
let a = new Hello('영서');
let b = new Hello('아름');
a.say() //Hello, 영서
b.say() //Hello, 아름
a._name = 'anonymous'
a.say() // Hello, anonymous
현재 Hello() 함수를 통해 생성된 객체들은 모두 _name이라는 변수를 가지게 됩니다. 변수명 앞에 underscore(_)를 포함했기 때문에 일반적인 JavaScript 네이밍 컨벤션을 생각해 봤을때 이 변수는 개인 변수(Private variable)로 쓰고싶다는 의도를 알 수 있습니다.
하지만 실제로는 여전히 외부에서도 쉽게 접근가능한 것을 확인할 수 있습니다.
이 경우 클로저를 사용하여 외부에서 직접적으로 변수에 접근할 수 없도록 캡슐화(은닉화)할 수 있습니다.
- 클로저(closure)란?
- 클로저(closure)는 함수와 그 함수가 선언됐을 때의 렉시컬 환경(Lexical environment)과의 조합이라고 부른다.
- 내부 함수가 외부(enclosing) 함수 변수에 액세스(접근) 할 수 있는 자바스크립트의 기능을 말한다.
function hello(name) {
let _name = name;
return function () {
console.log('Hello, ' + _name);
};
}
let a = new hello('영서');
let b = new hello('아름');
a() //Hello, 영서
b() //Hello, 아름
이렇게 a와 b라는 클로저를 생성함으로써 함수 내부적으로 접근이 가능하도록 만들 수 있습니다.
조금 더 간단한 예제
function a(){
let temp = 'a'
return temp;
}
// console.log(temp) error: temp is not defined
const result = a()
console.log(result); //a
현재 위 함수 내부적으로 선언된 temp에는 직접적으로 접근을 할 수 없습니다. 함수 a를 실행시켜 그 값을 result라는 변수에 담아 클로저를 생성함으로써 temp의 값에 접근이 가능합니다.
함수 안에 값을 숨기고 싶은 경우 클로저를 활용해볼 수 있습니다.