bata's log

フロントエンド系のTipsとかメモ

JavaScriptでクラス継承みたいなものをやってみる

JavaScriptにはそもそもクラスなんてないし~(ry、とかプロトタイプチェーンが~(ryとかの話はひとまずスルーして、実際に使用出来そうなクラス継承を考えてみた。

クラスを継承する

クラスの継承は.call()関数や.apply関数を使用します。

function A(n){
    this.n = n;
    this.n10 = n * 10;
}

A.prototype.hoge = function(){
    return this.n + this.n10
}

function B(n){
    //Aクラスを継承
    A.call(this,n);
    //Bクラスのプロパティ
    this.n = n+n
}

//init
var b = new B(1);
console.log(b.n,b.n10) //2,10

BクラスでAクラスのプロパティthis.n10を使うことが出来るようになります。

prototypeに追加したメソッドを継承する

上記でクラスのプロパティを継承できましたが、これだけではprototypeに追加したメソッドを継承する事はできません。継承元クラスのインスタンスを継承先のprototypeに代入して、BクラスからAクラスのメソッドを使用できるようにします。

~~~
//プロトタイプにインスタンスを代入
B.prototype = new A();

//プロトタイプを代入する場合(※追記)
//B.prototype = A.prototype;

//init
var b = new B(1);
console.log(b.hoge()); //12

本来Bクラスにはないメソッドhoge()が使用可能になります。
(※追記)A.prototypeを代入してしまってもOKですね、これ。

↑は継承では無いとのご指摘あったので、、、確かに階層構造にはなってない。

http://qiita.com/LightSpeedC/items/d307d809ecf2710bd957
こちらが参考になりました。
両方共やっちゃいけないに分類されてるな...

おまけ

メソッド名が被った場合に継承先を優先させるように(上書きされないように)マージする方法です。

~~~
//オブジェクトをマージする関数
function merge(dest, base) {
    //継承元にオブジェクトがない場合
    if (!base) {
        base = {};
    }
    for (var prop in base) {
        //継承元にプロパティが存在し、かつ継承先にプロパティがない場合にマージ
        if (base.hasOwnProperty(prop) && !dest.hasOwnProperty(prop)) {
            dest[prop] = base[prop];
        }
    }
};

//A.prototypeをB.prototypeにマージする
merge(B.prototype,A.prototype);

//init
var b = new B(1);
console.log(b.hoge()); //12;