ANTON072
7/15/2013 - 1:59 PM

Javascriptにおけるクラスの実装方法

Javascriptにおけるクラスの実装方法

Javascriptでクラスを継承する方法

Jsにはクラスがないので正確ではないけど気にしない

クラス宣言

Javascriptのクラスの宣言は主に

  • var Hoge = function(){}
  • function Hoge() {}

の2通りがある

http://qiita.com/VoQn/items/5df25f771d4602fd6293 によると、前者のやり方をしている場合、後述するObject.create()メソッドを使った継承を行うと

  console.log(hogeChildObj);  // hogeChildObjはHogeを継承したクラスのインスタンス

が[object]としか出なくなりデバッグがしづらくなるらしい。

よってクラス宣言は後者のfunction型にしておく

本題の継承方法について

参考ページ: https://gist.github.com/yoshimuraYuu/3301790

継承の際に気をつけるのは以下の2つ

  • プロパティ
  • メソッド

プロパティ

親のプロパティを子に引き継がせたい場合はParent.apply(this)を呼べばよい

function Parent() {

}

function Child() {
    Parent.apply(this);
}

こうすることで親のプロパティが子に引き継がれる。 引数が存在する場合でも以下のようにして簡単に引数を親クラスに渡すことができる

function Child() {
    Parent.apply(this, arguments);
}

メソッド

次に、メソッドにあたるプロトタイプの宣言についてはよく以下の様な実装が用いられるが、 上に挙げたgistの参考ページにもあるようにいろいろと問題がある。

// これは微妙らしい
Child.prototype = new Parent();

いちいちコンストラクタをnewするのも実装的に綺麗ではないし、あまりやりたくないところではある。

そこで、参考ページも出ていた、ECMAScript5から採用されているObject.create()メソッドを用いる https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/create

mozillaのページの方は少々わかりづらいが、オライリーの「Javascriptパターン」によると

function create(obj) {
    function F(){}
    F.prototype = obj;
    return new F();
}

のような実装がされているということなので、このパターンを用いるとプロトタイプの継承が以下のようにスッキリ書ける。

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

これでだいぶ綺麗にはなったが、さらにunderscore.jsのextendメソッドを使ってChildから定義するmethodもまとめる

var _ = require('underscore') // node.jsで起動する場合に記述する。ブラウザで実行する場合はこのソースの前にunderscore.jsを読み込んでおく

Child.prototype = _.extend(Parent.prototype, {
    constructor: Child,
    method1: function() { console.log("method1") }
});

これでクラスの定義がだいぶすっきり書けるようになった。