@ledsun blog

無味の味は佳境に入らざればすなわち知れず

JavaScriptのオブジェクト生成

JavaScriptには次の三つのオブジェクト生成方法があります。

  1. プロトタイプ風
  2. クラス風(異教徒の呪い、Fxxk your God!!!)
  3. 関数の束縛

比べてみましょう。

例に使う関数

ここに指定した文字に挨拶をする関数があります。

var hello = function(str) { return "hello " + str + "!"; };

hello("world"); //"hello world!"

この関数と文字をプロパティに持つオブジェクトを考えます。 各々の方法で生成してみましょう。

プロトタイプ風

関数を自身のプロパティを参照するように修正します。 引数は無く、代わりにthisで自オブジェクトのプロパティを参照します。

var greeter = {
    hello: function() { return "hello " + this.string + "!"; }
};

JavaScriptはプロトタイプベースオブジェクト指向言語です。 Object.create で元のオブジェクトの特性を継承した新しいオブジェクトを生成します。

var g1 = Object.create(greeter);
g1.string = "world";
g1.hello();
  • Object.create関数でオブジェクトのコピーを作ります。
  • 子オブジェクトに無いプロパティは親オブジェクトのものが使用されます。
  • メソッドはコピーされず参照されます。

また、ECMAScript5のObject.createは第二引数でプロパティを追加できます。

var greeterToTheWorld = Object.create(greeter, {
    string: { value: "world" }
});

greeterToTheWorld.hello();

クラス風(異教徒の呪い、Fxxk your God!!!)

クラスベースオブジェクト指向教徒の使う名状しがたい忌まわしい手法です。 彼らは異界の神Javaへの信仰を誓い、クラスの呪いから抜け出せなくなった哀れで醜い存在です。

var Greeter = function(str){
    this.string = str;
};

Greeter.prototype.hello = function (){
    return "hello " + this.string + "!";
};

var grtterToTheWorld = new Greeter("world");
grtterToTheWorld.hello();

コンストラクタインスタンスメソッド、prototypeプロパティ、new演算子、いずれも異教徒の忌まわしい言葉です。 聞くに堪えない、恐ろしくもおぞましいその響きを耳にするだけで身震いし、ある者は正気を失うといいます。使ってはいけません。

関数の束縛

オブジェクトを関数とその引数の組み合わせと考えると、単に関数に引数を束縛すればよいはずです。

var hello = function(str) { return "hello " + str + "!"; };

var greetToTheWorld = hello.bind(null, "world");
greetToTheWorld();

メソッドが一つなら最もシンプルです。Function.prototype.bindはECMAScript5で追加されました。使えない環境もあります。*1