MoyaSystem

もやしです。

JavaScript: ほかのオブジェクトのメソッドを拝借して新しいオブジェクトを作る

課題

新しいオブジェクトを作成する際に、既存のオブジェクトのメソッドをそのオブジェクトのメソッドとして呼び出せたらいいな、ということがあります。しかし、そのオブジェクトをまるごと継承するのは都合が悪いときもあります。そのような場合、一部のメソッドのみ拝借するという方法があります。

「格闘家」と「バスケ選手」から「サッカー選手」を作りたい例を考えてみましょう。サッカー選手は「kick」と「dribble」ができればよい、と仮定します。既にFighterオブジェクトとBasketballerクラスは用意されています。

    var Fighter = function Fighter(){};
    Fighter.prototype.panch = function(){
        console.log(this.name + " can panch!");
    };
    Fighter.prototype.kick = function(){
        console.log(this.name + " can kick!");
    };

    var Basketballer = function Basketballer(){};
    Basketballer.prototype.dribble = function(){
        console.log(this.name + " can dribble!");
    };
    Basketballer.prototype.dank = function(){
        console.log(this.name + " can dank!");
    };

格闘家はpanchとkickができ、バスケ選手はdribbleとdankができます。kickとdribbleのみサッカー選手に使わせたい場合、継承は適切な手段ではありません。

メソッド拝借

以下のようにすればメソッドを拝借することができます。

    var SoccerPlayer = function SoccerPlayer(){};
    SoccerPlayer.prototype.kick = function(){
        Fighter.prototype.kick.call(this);
    };
    SoccerPlayer.prototype.dribble = function(){
        Basketballer.prototype.dribble.call(this);
    }

    var honda = Object.create(SoccerPlayer.prototype,{
        name: {value: "Keisuke Honda"}
    });

    honda.kick(); // Keisuke Honda can kick!
    honda.dribble(); // Keisuke Honda can dribble!
    // honda.panch(); // error
    // honda.dank(); // error

SoccerPlayerオブジェクトを作成し、kick, dribleメソッドの中で、Fighter.prototype.kick, Basketballer.prototype.dribble の両関数が持っているcallメソッドを呼び出してやります。引数にSoccerPlayerオブジェクト自身(this)を渡すと、各メソッドはその呼び出し元であるthisにSoccerPlayerオブジェクトを束縛します。結果、SoccerPlayerオブジェクトのメソッドとしてkick, dribbleを呼び出すことができます。当然、panch, dankを呼び出すことはできません。

最後に

ブログ本文書いてからキックとドリブルができればサッカー選手ってそうとう無茶苦茶な説明だなと思ったんですが、あらためて新しい例を考えなおすのめんどくさかったのでそのままにしておきます。謹んでお詫びを申し上げます。