読者です 読者をやめる 読者になる 読者になる

ECMAScript 5th時代のクラス定義とインスタンス生成

JavaScript

オブジェクトの生成にnew演算子を使わないのが今どきらしい。じゃあ、どうすりゃいいのよ?

こんなんで良さげ。

var Hoge = Object.create({}, {
   // プロパティ
   val: { set: function(a){ this._a = a }, get: function(){ return this._a }},
   // メソッド
   add: { value: function(a){ this._a += a } },
   // イニシャライザ
   init: { value: function(a){ this.val = a; return this; } }
});

var h = Object.create(Hoge).init(1);
h.add(4);
h.add(2);
console.log("value:" + h.val)

メソッドはvalueにfunctionをセットして定義する。プロパティにする場合はsetとgetにセッター、ゲッターを指定。valueとset/getを同時に定義するとエラーになる。イニシャライザの名前は慣例にしたがってinitとしておく。イニシャライザではreturn thisが必須。

ただし、これはHogeオブジェクトのクローンを生成するだけなので、instanceof が使えない。型など要らんというprototype原理主義野郎はともかく、型も欲しいケースでは使えない。

型を作りたいときは、functionとdefinePropertiesを使ってクラスを定義。

var Hoge = function(){
  // 普通にnewされた場合もinitを呼ぶ。new禁止というなら例外でも投げておけ
  this.init.apply(this, arguments);
}
Object.defineProperties(Hoge.prototype, {
   // プロパティ
   val: { set: function(a){ this._a = a }, get: function(){ return this._a }},
   // メソッド
   add: { value: function(a){ this._a += a } },
   // イニシャライザ
   init: { value: function(a){ this.val = a; return this; } }
});

// newを使う
var h = new Hoge(1);
console.log(h instanceof Hoge)
h.add(4);
h.add(2);
console.log("value:" + h.val)

// newを使わない
var h2 = Object.create(Hoge.prototype).init(4);
console.log(h2 instanceof Hoge)
h2.add(4);
h2.add(5);
console.log("value:" + h2.val)

newを使用しないとタイプ量が増えてちょっと面倒な感じ。newで良いんじゃないかな…