User Object definition in JavaScript

あいかわらずJavaScriptについて色々調べてます。JavaScriptでユーザーオブジェクトを定義するには、つぎのような感じになります。コンストラクタ用の関数を定義して、定義したオブジェクトのprototypeに属性を追加していきます。操作の追加もできます。操作は実体を別に用意しておいて名前で束縛するという感じです。ただし、オブジェクト単位での名前空間は定義されないので、オブジェクト用の属性や操作の実体用に _ で始まる名前は予約しておいて、通常の関数では _ を使わないということを考えたりしないといけません。

// コンストラクタ
function Target() {
}
Target.prototype.name = “Target”
Target.prototype.equals = _target_equals;
Target.prototype.toString = _target_toString;

// このオブジェクトと他のオブジェクトが等しいかどうかを示します。
function _target_equals(obj) {
return obj.toString()==this.name;
}
// 文字列表現を返します。
function _target_toString() {
return this.name;
}

「実装の継承」らしきことを実現することもできるようですが、JavaScriptのオブジェクトに関しては型によるチェックはできないので個人的にはあまり意味がないかなという感じです。せっかく操作の実体を指定できるようになっているので、オブジェクトコンポジションの考え方で拡張していく方が、オブジェクトの役割もわかりやすくなりますから良いと思います。ソースコードが少々長くなりますけど、継承の罠にはまりにくくなるので、保守性は高まると思います。

JavaScriptにはObjectオブジェクトがあるので、それを継承する方法を紹介しておきます。(Objectオブジェクトは暗黙に継承されているようなので、明示的に指定する必要はないらしいのですが、例の紹介ということで示しておきます。)

// このオブジェクトと他のオブジェクトが等しいかどうかを示します。
function _extendedobject_equals(obj) {
return obj.toString()==this.name;
}
// オブジェクトの文字列表現を返します。
function _extendedobject_toString() {
return this.name;
}

// コンストラクタ
function ExtendedObject() {
// プロパティの初期化
this.base = Object;
this.base();
this.name = “ExtendedObject”

// メソッドのバインディング
this.equals = _extendedobject_equals;
this.toString = _extendedobject_toString;
}
ExtendedObject.prototype = new Object;

function _subobject_setPoint(point) {
this.point = point;
}
function _subobject_getPoint() {
return this.point;
}
function SubObject() {
this.base = ExtendedObject;
this.base();
this.point = 100;
this.setPoint = _subobject_setPoint;
this.getPoint = _subobject_getPoint;
}
SubObject.prototype = new ExtendedObject;

ここでは、Object <- ExtendedObject <- SubObject という関係のオブジェクト定義をしています(<-は継承の意味)。JavaScriptの場合は動的に属性や操作を追加できてしまうので、ちょっと慣れないとわかりにくい感じがします。

同じカテゴリの記事: etc