野次馬エンジニア道

野次馬な気持ちでプログラミングをあれこれと綴ります

JavaScriptでオブジェクト指向 (1) - クラス定義

プロトタイプベースのオブジェクト指向とよく本に書かれていますがいまいちピンとこない。早速野次馬的に入門してみます。

オブジェクト

型がなきゃ不安だ。という訳で見慣れたリテラルをオブジェクトとして見てみる。

var a = {foo:bar}; 
var a = new Object();
a.foo = bar; // と同じ。

コンストラクタ

JavaScriptは全てオブジェクト。コンストラクタも実体は関数オブジェクト。

var Foo = function(){}
var bar = new Foo(); 
Foo(); // new経由で呼び出さないとundefined.                
bar.__proto__ === Foo.prototype // true
bar.constructor.prototype ===  Foo.prototype // true
bar.constructor.name // Foo

__proto__は全てのオブジェクトが持つ隠しプロパティ。

ここで

  • function式で生成されるのは、関数オブジェクト。new Function(...)と同じ
  • 全ての関数はprototypeプロパティを持つ
  • __proto__は、コンストラクタ関数のprototypeプロパティを指す

に着目。new経由の呼びだしでは、内部的にインスタンス(bar)の__proto__にコンストラクタ関数のprototypeプロパティがセットされる動作となる。これが特に重要。

プロトタイプチェーン

なぜか?JavaScriptは、自身に関数やプロパティが見つからなかった場合に、__proto__を辿る。プロトタイプチェーンを具体的なコードで書くと、__proto__.__proto__.__proto__.__proto__...となるイメージ。

チェーンの終端では、Object.prototype.__proto__ がNULLになっている。終端まで行って見つからない場合undefinedとなる。

プロトタイプベース

コンストラクタとなる関数オブジェクトが持つprototypeプロパティと、__proto__をチェーンで辿る仕組みがJavaScriptのプロトタイプベースのオブジェクト指向の根幹となる。

Javaメソッドやフィールドを解決するためにクラスを参照するのでクラスベース。対してJavaScriptではプロトタイプを辿るのでプロトタイプベースと呼ばれる。

プロトタイプへのメソッドとプロパティの追加

プロトタイプにメソッドとプロパティを追加してクラスを定義してみる。

var Foo = function(_name){
 this.name = _name;
}
Foo.prototype.greet = function(){
    return "hello my name is "+ this.name;
}
var my = new Foo("bar");
my.greet(); // hello my name is bar.
my.name // bar

ここまでが基本。次回はプロトタイプチェーンを使って継承を見てみる。