코드 재사용 패턴(클래스 방식의 상속) - 생성자 빌려쓰기

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

 

코드 재사용 패턴(클래스 방식의 상속) - 생성자 빌려쓰기

 


function Child(a, c, b, d){
    Parent.apply(this, arguments);
}

 

설명

  • 부모 생성자 함수의 this에 자신 객체를 바인딩한 다음, 자식 생성자가 받은 인자들을 넘겨준다.

  • 부모 생성자 함수 내부의 this에 추가된 프로퍼티만 상속

  • 프로토타입에 추가된 멤버는 상속되지 않는다.

 

※ 기본패턴과의 차이점

기본패턴의 경우 자식 객체가 상속된 멤버의 참조를 물려받은 받지만, 생성자 빌려쓰기 패턴을 사용하면 자식 객체는 상속된 멤버의 복사본을 받게 된다.



// 부모 생성자
function Article() {
    this.tags = ['js', 'css'];
}
var article = new Article();


// 클래스 방식의 패턴 #1 사용, article 객체를 상속하는 blog 객체 생성
function BlogPost() {}
BlogPost.prototype = article;
var blog = new BlogPost();


// 생성자 빌려쓰기 패턴 사용, article 객체를 상속하는 page 객체 생성
function StaticPage() {
    Article.call(this);
}
var page = new StaticPage();


alert(article.hasOwnProperty('tags'));  // true
alert(blog.hasOwnProperty('tags'));     // false
alert(page.hasOwnProperty('tags'));     // true

blog.tags.push('html');
page.tags.push('php');

alert(article.tags.join(', '));         // js, css, html
alert(page.tags.join(', '));            // js, css, php

 

설명

  • blog 객체의 경우 tags를 자기 자신의 프로퍼티로 가진 것이 아니라 프로토타입을 통해 접근하기 때문에 hasOwnProperty()로 확인 시 false 반환.

  • blog 객체가 tags 프로퍼티 수정 시 부모의 멤버도 수정, blog.tags와 article.tags는 동일한 배열을 가리키고 있다.

  • page.tags는 상속 과정에서 별개로 생성된 복사본이기 때문에 영향이 없다.

 

 

프로토타입 체인



// 부모 생성자
function Parent(name) {
    this.name = name || 'Parent';
}


// 프로토타입에 기능 추가
Parent.prototype.say = function() {
    return this.name;
}


// 자식 생성자
function Child(name) {
    Parent.apply(this, arguments);
}


var kid = new Child('Child');
kid.name;                        // 'Patrick'
typeof kid.say;                  // undefined

 

구조

                  

 

설명

  • 생성자 빌려쓰기 패턴의 경우, 연결고리가 유지되지 않은 프로토타입 체인

  • 상속은 부모가 가진 자신만의 프로퍼티를 자식의 프로퍼티로 복사해주는 일회성 동작이며, __proto__ 라는 링크는 유지되지 않는다.

 

 

생성자 빌려쓰기 패턴을 적용한 다중 상속



function Cat() {
    this.legs = 4;
    this.say = function() {
        return "yaa";
    }
}

function Bird() {
    this.wings = 2;
    this.fly = true;
}

function CatWings() {
    Cat.apply(this);
    Bird.apply(this);
}

var test = new CatWings();
console.dir(test);

 

 

 

 

 

설명

  • 생성자를 하나 이상 빌려쓰는 다중 상속 구현 가능

  • 중복 프로퍼티 존재시 마지막 프로퍼티 값으로 덮어쓴다.

 

 

생성자 빌려쓰기 패턴 장단점

  • 프로토타입이 상속되지 않는 점은 이 패턴의 한계

  • 재사용되는 메서드와 프로퍼티는 인스턴스별로 재생성되지 않도록 프로토타입에 추가

  • 부모 생성자 자신의 멤버에 대한 복사본을 가져올 수 있다는 것은 장점, 이 장점으로 인해 자식이 실수로 부모의 프로퍼티를 덮어쓰는 위험을 방지

 

 

 

출처 : JavaScript Patterns