개요

객체를 다른 객체에 중첩하면 내부 객체를 참조 혹은 값으로 취급할 있다.

참조, 차이는 다음과 같다.

참조로 다루는 경우는 내부 객체는 그대로 객체 속성만 갱신한다.

값으로 다루는 겨우는 새로운 속성을 담은 객체로 기존 객체를 대체한다.

 

필드를 값으로 다루고 싶다면 내부 객체의 클래스를 수정하여 객체로 만들면 된다.

객체는 불변이기에 자유롭게 활용할 있다.

불변이라면 외부로 값을 내줘도 몰래 값이 변경되어 내부에 영향 받을 걱정이 없다.

특징은 특히 분산 시스템과 동시성 시스템에서 유용하다.

 

예시



//아직 전화번호가 올바로 설정되지 못하게 짜여 있다고 가정
class Person{
    constructor(){
        this._telephoneNumber = new TelephoneNumber();
    }
    get officeAreaCode(){return this._telephoneNumber.areaCode;}
    set officeAreaCode(arg){this._telephoneNumber.areaCode = arg;}
    get officeNumber(){return this._telephoneNumber.officeNumber;}
    set officeNumber(arg){this._telephoneNumber.officeNumber = arg;}
}
class TelephoneNumber{
    get areaCode(){return this._areaCode;}
    set areaCode(arg){this._areaCode = arg;}
    get number(){return this._number;}
    set number(arg){this._number = arg;}
}


class TelephoneNumber{
    //불변으로 만들기 위해 세터 제거 후 생성자로만 받는다.
    constructor(areaCode, number){
        this._areaCode = areaCode;
        this._number = number;
    }
    get areaCode(){return this._areaCode;}
    get number(){return this._number;}
}


class Person{
    constructor(areaCode,officeNumber){
        this._telephoneNumber = new TelephoneNumber();
    }
    get officeAreaCode(){return this._telephoneNumber.areaCode;}
    //값을 설정할 때 마다 매번 새로운 객체를 리턴한다.
    set officeAreaCode(arg){this._telephoneNumber = new TelephoneNumber(arg, this.officeNumber);}
    get officeNumber(){return this._telephoneNumber.officeNumber;}
    set officeNumber(arg){this._telephoneNumber = new TelephoneNumber(this.officeAreaCode,arg);}
}
이제 전화번호 클래스는 불변 클래스이다.
이제 논리적 동치성을 위해 기반 비교를 해야한다.
자바스크립트는 참조 기반 동치성을 기반 동치성으로 대체하는 메서드가 없다.
그냥 equals()함수를 직접 만든다.


class TelephoneNumber{
    constructor(areaCode,officeNumber){
        this._areaCode = areaCode;
        this._officeNumber = officeNumber;
    }
    get areaCode(){return this._areaCode;}
    set areaCode(arg){this._areaCode = arg;}
    get number(){return this._number;}
    set number(arg){this._number = arg;}
    //논리적 동치성 검사 메서드
    equals(other){
        if(!(other instanceof TelephoneNumber)) return false;
        return Object.keys(this).every(a=>this[a] === other[a]);
    }
}


class TelephoneNumber{
    constructor(areaCode, number){
        this._areaCode = areaCode;
        this._number = number;
    }
    get areaCode(){return this._areaCode;}
    get number(){return this._number;}
    //논리적 동치성 검사 메서드
    equals(other){
        if(!(other instanceof TelephoneNumber)) return false;
        return Object.keys(this).every(a=>this[a] === other[a]);
    }
}


class Person{
    constructor(){
        this._telephoneNumber = new TelephoneNumber();
    }
    get officeAreaCode(){return this._telephoneNumber.areaCode;}
    set officeAreaCode(arg){this._telephoneNumber = new TelephoneNumber(areaCode, this.officeNumber);}
    get officeNumber(){return this._telephoneNumber.officeNumber;}
    set officeNumber(arg){this._telephoneNumber = new TelephoneNumber(this.officeAreaCode, arg);}
}
class TelephoneNumber{
    constructor(areaCode, number){
        this._areaCode = areaCode;
        this._number = number;
    }
    get areaCode(){return this._areaCode;}
    get number(){return this._number;}
    //논리적 동치성 검사 메서드
    equals(other){
        if(!(other instanceof TelephoneNumber)) return false;
        return Object.keys(this).every(a=>this[a] === other[a]);
    }
}
const t1 = new TelephoneNumber("12345","67890");
const t2 = new TelephoneNumber("12345","67890");
console.log(t1.equals(t2));

 

 

 

+ Recent posts