본문으로 바로가기

6. 객체지향 프로그래밍 (3)

category language/JavaScript 2019. 12. 2. 19:35

6.3 캡슐화

캡슐화 : 기본적으로 관련된 여러 가지 정보를 하나의 틀 안에 담는 것


멤버 변수와 메서드 : 서로 관련된 정보

클래스 : 이것을 담는 하나의 큰 틀


중요한 것은 정보의 공개 여부

—> 정보 은닉 (information hiding)


예제 6-9

var Person = function(arg) {
    var name = arg ? arg : "zzoon";

    this.getName = function() {
        return name;
    }
    this.setName = function(arg) {
        name = arg;
    }
};

var me = new Person();
console.log(me.getName());  // zzoon
me.setName("iamhjoo");
console.log(me.getName());  // iamhjoo
console.log(me.name);   // undefined

 

this 객체의 프로퍼티로 선언하면 외부에서 new 키워드로 생성한 객체로 접근할 수 있다.

하지만 var로 선언된 멤버들은 외부에서는 접근이 불가능하다.

그리고 getName, setName 메서드 (퍼블릭) 가 클로저 역할을 하면서 name 멤버 (프라이빗) 에 접근할 수 있다.

이것이 자바스크립트에서 할 수 있는 기본적인 정보 은닉 방법!


예제 6-10 모듈 패턴

var Person = function(arg) {
    var name = arg ? arg : "zzoon";

    return {
        getName : function() {
            return name;
        },
        setName : function(arg) {
            name = arg;
        }
    };
}

var me = Person();  /* or var me = new Person(); */
console.log(me.getName()); // zzoon

 

예제 6-10은 예제 6-9를 좀더 깔끔하게 다듬은 것.

Person 함수를 호출하여 객체를 반환받는다. 이 객체에 Person 함수의 private 멤버에 접근할 수 있는 메서드들이 담겨 있다. 사용자는 반환받는 객체로 메서드를 호출할 수 있고, private 멤버에 접근할 수 있다. 이렇게 메서드가 담겨 있는 객체를 반환하는 함수는 여러 유명 자바스크립트 라이브러리에서 쉽게 볼 수 있는 구조이다.


다만 접근하는 private 멤버가 객체나 배열이면

얕은 복사로 참조만을 반환

하므로 사용자가 이후 이를 쉽게 변경할 수 있다.


예제 6-11

var ArrCreate = function(arg) {
    var arr = [1, 2, 3];
    
    return {
        getArr : function() {
            return arr;
        }
    };
}

var obj = ArrCreate();  /* or var obj = new ArrCreate(); */
var arr = obj.getArr();
arr.push(5);
console.log(obj.getArr());  // [1, 2, 3, 5]

 

이런 문제가 있으므로 프로그래머는 객체를 반환하는 경우 신중해야 한다. 보통의 경우, 객체를 반환하지 않고 객체의 주요 정보를 새로운 객체를 담아서 반환하는 방법을 많이 사용한다. 하지만 꼭 객체가 반환되어야 하는 경우에는 깊은 복사로 복사본을 만들어서 반환하는 방법을 사용하는 것이 좋다.


다시 예제 6-10으로 돌아가서, 여기서 사용자가 반환받은 객체는 Person 함수 객체의 프로토타입에는 접근할 수 없다는 단점이 있다. 이는 Person을 부모로 하는 프로토타입을 이용한 상속을 구현하기가 용이하지 않다는 것을 의미한다.

이를 보완하려면 객체를 반환하는 것이 아닌, 함수를 반환하는 것이 좋다.


예제 6-12

var Person = function(arg) {
    var name = arg ? arg : "zzoon";
    
    var Func = function() {}
    Func.prototype = {
        getName : function() {
            return name;
        },
        setName : function(arg) {
            name = arg;
        }
    };
    
    return Func;
}();

var me = new Person();
console.log(me.getName());

 

즉시 실행 함수에서 반환되는 Func이 클로저가 되고 이 함수가 참조하는 name 프로퍼티가 자유 변수가 된다. 따라서 사용자는 name에 대한 접근이 불가능하다.



#책/인사이드자바스크립트