코드 재사용 패턴(새로운 방식의 상속) - 프로퍼티 복사를 통한 상속 패턴

2020. 3. 2. 15:13웹/Javascript Pattern

코드 재사용 패턴(새로운 방식의 상속) - 프로퍼티 복사를 통한 상속 패턴

function extend(parent, child) {
    var i;
    child = child || {};
    for(i in parent) {
        if(parent.hasOwnProperty(i)){
            child[i] = parent[i];
        }
    }
    return child;
}

var parent = {
    name : "Parent"
};

var kid = extend(parent);
kid.name;   // Parent

설명

  • 부모의 멤버들에 대해 루프를 돌면서 자식에 복사

  • 두번째 매개변수는 생략 가능

  • 인자가 생략되면 상속을 통해 기존 객체의 기능이 확장되는 대신, 새로운 객체가 생성 및 반환

  • 얕은 복사(shallow copy)

 

※ 깊은 복사

복사하려는 프로퍼티가 객체나 배열인지 확인해보고, 객체 또는 배열이면 중첩된 프로퍼티까지 재귀적으로 순회하여 복사

 

 

var parent = {
    counts: [1, 2, 3],
    reads : {paper: true}
};

var child = extend(parent);
child.counts.push(4);

parent.counts.toString();      // 1,2,3,4
parent.reads === child.reads;  // true

설명

  • 자바스크립트에서 객체는 참조만 전달하기 때문에 얕은 복사를 통해 상속을 실행한 경우, 자식쪽에서 객체 타입인 프로퍼티 값을 수정하면 부모의 프로퍼티도 수정되어 버린다. 

  • 함수 역시 객체이고 참조만 전달되기 때문에, 메서드는 이런 방식으로 복사되는게 더 좋을 수 있다. 그러나 객체와 배열을 다룰 때는 예기치 못한 결과가 나올수 있다.

 

function extendDeep (parent, child) {
    var i,
        toStr = Object.prototype.toString,
        astr = "[object Array]";
    child = child || {};
    
    for(i in parent) {
        if(parent.hasOwnProperty(i)) {
            if(typeof parent[i] === "object") {
                child[i] = (toStr.call(parent[i]) === astr) ? [] : {};
                extendDeep(parent[i], child[i]);
            } else {
                child[i] = parent[i];
            }
        }
    }
    return child;
}

var parent = {
    counts : [1,2,3],
    reads  : {paper : true}
};
var child = extendDeep(parent);

child.counts.push(4);
child.counts.toString();       // 1,2,3,4
parent.counts.toString();      // 1,2,3

parent.reads === child.reads; // true
child.reads.paper = false;
child.reads.web = true;
parent.reads.paper;           // true

설명

  • 프로퍼티의 타입이 객체인지 확인하여, 객체가 맞으면 재귀적으로 복사하는 기능 추가

  • 깊은 복사 수행

 

 

 

출처 : JavaScript Patterns