JavaScriptのオブジェクトを別のオブジェクトと合成させるメソッドを実装してみた

注意 (追記: 2014年1月2日)

baseメソッドを使うとIE8で問題が発生しましたので、baseメソッドを非推奨とします。この記事は、検証用に残しておきます。

新しいメソッドの実装

インスタンスベースのオブジェクト指向をしたい場合、JavaScriptには、Object.create関数があるのですが、グローバル変数だったり、第二引数があるなど、いまいち、使いづらかったので、新しいメソッド「this.base」を作ってみました。
この新しいメソッド「this.base」を使うと、呼び出し側のオブジェクトをベースに、第一引数のオブジェクトと合成したようなオブジェクトを生成して返します。

作り方

次のコードを最初にコピーするだけでOK。

this.base= function(obj) {
  if (!arguments[0]) {
    throw new Error();
  }
  var F = function() {},
      s;
  F.prototype = this;
  s = new F();
  if (typeof obj !== "function") {
    for (var i in obj) {
      if (obj.hasOwnProperty(i)) {
        s[i] = obj[i];
      }
    }
  } else {
    obj.call(s);
  }
  F = void 0;
  return s;
};

this.baseのthisは、グローバルオブジェクトです。多くのブラウザだとwindowなのですが、環境に依存してしまうため、windowのかわりに、thisを用いています。

使い方

使い方は以下のとおりです。

this.$parent = this.base(function(){
  this.$child = this.base( {
                   a: 20,
                   b: 12
                });
});
this.$parent.$child.b; // 12
this.$parent.c = 15;
this.$parent.$child.c; // 15

ちなみに、関数を引数として入れると、プロトタイプを使って、関数内部のthisに新しいオブジェクトを入れてくれます。
このサンプルのコードでは、親オブジェクトとして、this.$parentを作っています。さらに、this.baseを使って、this.$parent.$childに、$parentを継承させています。親オブジェクトのcプロパティに、15を設定しましょう。すると、子オブジェクトの、$childのcプロパティもまた、プロトタイプ継承により、数値の15を呼び出すことができるのです。

グローバル変数を消去できるメリット

それで、このメリットは何かといいますと、サンプルコードを見ていただければわかりますように、「グローバル変数を除去できる」ということです。
つまり、グローバル変数を一切使わずに、JavaScriptを書くことができるということです。ただし、グローバルオブジェクトは除きます。
SIEでは、グローバル変数を数多く作っていますので、これを名前空間として使えればいいなと思っています。