メンテナンス中なので、はてなダイアリの方ににメモ。Site Manager(自作似非ぶろぐましん)の複製でテストすりゃあ良かったのに馬鹿だなあもう。
それはさておき今更ながらECMAScript仕様書を読み終えんぬ。継承元のコンストラクタを遡及的に呼ぶ為のおまじないを書きつつ、概ねスタイルが出来上がってきた。
// そのおまじない(プロトタイプチェインの末端に仕掛けた例)
Object.prototype.__super__ = function(){
arguments[arguments.length-1].callee.__super__.apply(this, arguments); };
Function.prototype.inherit = function(superClass) {
/* See http://www.skipup.com/~peace/javascript/ */
this.__super__ = superClass;
function Temp(){}
Temp.prototype = superClass.prototype;
this.prototype = new Temp;
this.prototype.constructor = this; };
// スーパークラス(コンストラクタ)の例
function SuperClass(arg1) {
this.p1 = arg1;
}
(function(proto){
proto.getP1 = function(){
privateMethod.call(this); // 呼び方
return this.p1; };
// スコープを変更する意味の一例
// でも継承先のメソッドからは参照できない
function privateMethod(){ /* .. */ };
})(SuperClass.prototype);
// サブクラス(コンストラクタ)の例
function SubClass(arg1, arg2){
this.__super__(arg1, arguments); // 必ず仮引数の最後にarguments
/* 他の書き方(こうすると自由にコンストラクタを選べるけれど
)
1. SuperClass.call(this, arg1);
2. this.__super__ = SuperClass;
this.__super__(arg1);
*/
this.p2 = arg2;
}
SubClass.inherit(SuperClass);
(function(proto){
proto.getP2 = function(){ return this.p2; };
})(SubClass.prototype);
Pythonみたいに__super__メソッド一発で呼びたかっただけなのに色々苦労したけれど、実際あまり意味が無かった。でもおかげでもうこのprototype辺りで混乱することは無くなった。ような気がする。
やっぱりObjectのprototypeに設定するのは危険というかナンセンスなので修正。
Function.prototype.inherit = function(superClass) {
/* See http://www.skipup.com/~peace/javascript/ */
this.__super__ = superClass;
function Temp(){}
Temp.prototype = superClass.prototype;
this.prototype = new Temp;
this.prototype.__super__ = function(){
arguments[arguments.length-1].callee.__super__.apply(this, arguments); };
this.prototype.constructor = this; };
継承時に、コンストラクタのprototypeに設定。プロトタイプチェインを考えると、Objectかこっちか、どちらかしか選択肢は無い。筈。インスタンスに直接設定するなら全く意味無いし。