2006年10月18日 21:00 [Edit]
javascript - プロトタイプ的継承完全版
Kazuho@Cybozuさま、いつもありがとうございます。
Kazuho@Cybozu Labs: JavaScript の String 型を継承する結論から言うと、String 型も継承っぽいことができます。こんな感じ。
おかげでプロトタイプ的継承モデルの完全版が出来ました。
AtomicなObjectを継承
これは、以下のように包括的に出来ます。
var Atomic = function(C){
var P = function(v){ this._v = v; };
P.prototype = new C;
P.prototype.valueOf = function(){ return this._v.valueOf(); }
P.prototype.toString = function(){ return this._v.toString(); }
return P;
}
使うときはこんな。
var MyStr = Atomic(Str);
MyStr.prototype.x = function(n){
var str = '';
while (n--) str += this;
return new MyStr(str);
};
var mystr = new MyStr("foobar");
しかし、このままではAtomicな場合とそうでない場合を分けなければなりません。
object()の拡張
そこで、object()を以下のように拡張します。
var object = function(obj, base) {
var P;
switch ( typeof(obj) ) {
case "boolean":
case "number":
case "string":
P = Atomic((base || obj).constructor);
break;
// case "array": typedof([]) is "object".
case "object":
P = function(){};
P.prototype = (base || obj);
break;
default:
return;
};
P.prototype.method = function(o, f){
if (typeof(o) == "string"){
P.prototype[o] = f;
}else{
for (var p in o){
P.prototype[p] = o[p];
}
}
}
return new P(obj);
}
これで、どんなObjectに対しても、obj.method()を使ってメソッドを追加できます。
var mystr = object("foobar");
mystr.method('x', function(n){
var str = '';
while (n--) str += this;
return new MyStr(str);
});
しかし、このままではSingleton Methodの追加しか出来ないことになります。やはり大々的に使うには
var MyStr = function(o){
// constructor を定義
}
var mystr = new MyStr("foobar");
var double = mystr.x(2);
のようにしたいところです。
Fake Constructorの定義
このMyStr()の定義をどうすればよいでしょうか?こうすればよいのです。
var MyStr = function(o){
var self = object(o);
self.method({
'x': function(n){
var str = '';
while (n--) str += this;
return new MyStr(str);
},
/* 他のmethodもここで定義 */
});
return self;
}
ここで注目して頂きたいのは、MyStr()はthisにはノータッチなことです。だからMyStr.prototype.x = function(){ /*... */ }は出来ません。しかし、その役割はself.method()が担っています。
あとは、
var mystr = new MyStr("foobar"); // 実はnewはあってもなくてもよい。
var double = mystr.x(2);
とすればいいわけです。
デモ
まとめると、こんな感じになります。
Boolean
Number
String
Array
Object
なんか足にささってなかなか抜けなかった刺が抜けた気分です。
Enjoy!
Dan the Prototyper
Posted by dankogai at 21:00│Comments(0)│TrackBack(5)
この記事へのトラックバックURL
この記事へのトラックバック
最近、プロトタイプ的継承の話しが盛り上がっています。 http://blog.livedoor.jp/dankogai/archives/50662064.html http://labs.cybozu.co.jp/blog/kazuho/archives/2006/10/javascript_string.php http://blog.livedoor.jp/dankogai/archives/50662606.html 最終形がやた
[javascript] 関数一発でプロトタイプチェーンに繋げて、オブジェクトをクローンする。【IT戦記】at 2006年10月19日 05:31
「404 Blog Not Found:javascript - プロトタイプ的継承」とその続編「404 Blog Not Found:javascript - プロトタイプ的継承完全版」は、案の定反応すべきbloggersが然るべき反応をしてくれた。これをbloggingの魅力と言わずしてなんと呼ぼうか。
プリミティブ値でもプ....
javascript - Prototypal Object Modelの落とし穴【404 Blog Not Found】at 2006年10月19日 11:39
メモ
http://blog.livedoor.jp/dankogai/archives/50662606.html
JavaScript【Miscellaneous】at 2006年10月19日 13:06
Perl5の欠点:Object Systemが後付けなこと。
Perl5の利点:Object Systemが跡づけなこと。
perl - Object::PrototypeでPOMを実装【404 Blog Not Found】at 2006年10月22日 22:23
404 Blog Not Found:javascript - プロトタイプ的継承完全版
404 Blog Not Found:javascript - プロトタイプ的継承完全版【】at 2012年01月23日 02:30