앞서 IIFE(즉시실행함수호출)을 활용을 하면, 함수를 통해 변수에 대한 접근을 은닉화를 할 수 있다고 이야기를 한 적이 있었습니다.
아래 예제를 통해 다뤄보도록 하겠습니다.
(function () {
var a = 'a';
})();
console.log(a); // a is not defined
함수 외부에서 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으로 쓰고싶다는 의도를 알 수 있습니다.
하지만 실제로는 여전히 외부에서도 쉽게 접근가능한 것을 확인할 수 있습니다.
이 경우 클로저를 사용하여 외부에서 직접적으로 변수에 접근할 수 있도록 캡슐화(은닉화)할 수 있습니다.
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
의 값에 접근이 가능합니다.
이렇게 함수 안에 값을 숨기고 싶은 경우 클로저를 활용해볼 수 있습니다.
안녕하세요, 깔끔한 글 잘 읽었습니다. 혹시 중간에 "클로저를 사용하여 외부에서 직접적으로 변수에 접근할 수 있도록 캡슐화(은닉화)할 수 있습니다." 라는 문장에서 "외부에서 직접적으로 변수에 접근할 수 없도록 캡슐화 할 수 있습니다." 가 되어야 하는 것 맞나요? 오타인지 아닌지 헷갈려서 댓글 남깁니다:)