Hatena::Groupgeneration1986

tyoro.g86

86世代と全然絡んでない人の日記

2008-06-04

継承関数

03:15

昨日のソース書かないといけないと思ってた事書くの忘れてた。

継承を自前でやるのが面倒だったのでinheritって関数はこちらから拝借した。

JavaScriptによるオブジェクト指向プログラミング

(ってかこれ9年前の記事か!古っ!

それ以前にos0xさんの記事からprototypeにあるような(ってかYUIに近い?)extendって関数を拝借してたんだけど、これには問題があった。

JavaScript継承パターンまとめ - Thousand Years

function extend(s, c)
{
	function f(){};
	f.prototype = s.prototype;
	c.prototype = new f();
	c.prototype.superclass = s.prototype;
        c.prototype.superclass.constructor = s;
	c.prototype.constructor = c;
	return c;
};

Sprite = extend(Window, function(img,id,css,pos,parent)
{
    this.superclass.constructor(id,css,pos,parent);

    //hogehoge

});

ちゃんと検証してないので確証は無いけど、この実装のままだと、Windowのコンストラクタ内でthis使ってた時に、生成したSpriteクラス全てでthisの内容を共有する羽目になるっぽい?

2個Sprite作って先に作った方のaction読んでるのに、後から登録した方が移動するという珍現象とぶつかって、原因解明大変だった。

これに気付くのに一番時間かかった。

楽しようとするとダメね。


せっかくサイ本読書会もprototypeの範囲越えたし、継承に利用する関数について一回ちゃんと検証した方が良さそう。

自分への宿題。

検証した

21:38

function A(ob){
    this.ob = ob;
}
B= extend(A, function()
{
    this.superclass.constructor(this);
});

a = new Array();
a = new B(1);
b = new B(2);
console.debug(a.ob == b.ob);//true
console.debug(a == b);//false
console.debug(a.ob == b);//true
console.debug(a.ob == b);//true

どう見てもthis共有してます。

ってか親コンストラクタのthisはsuperclassのthisになんのかな?

とりあえず呼び出しを

this.superclass.constructor.apply(this,[this]);

って形にしたら全部falseが帰ってくるようになりますた


inheritで実装してる方もapply使うとスマートになるだろうから、どっち使っても変わらん気もするけど、継承先のclassコンストラクタ内で継承元のclass関数名を書かねばならいあたり、inheritの方が冗長な気がするので、次の実装ではextendに戻すかな。

ただ、extendってJScriptでは将来的な予約語になってるらしいので、関数名変えた方が良さそう。

os0xos0x2008/06/18 13:42だいぶ反応遅いけど、
this.superclass.constructor(this);

this.superclass.constructor.apply(this,arguments);
にすると良い感じかも。