基底クラスコンストラクタ呼び出しの落とし穴2005年12月09日 13時14分

基底クラスのコンストラクタを呼び出す話に関連して。「Graviness Blog」と「JavaScriptっぽい。」で示された解決策には少し問題がある。inherit(SubClass, SuperClass) としたとき、SuperClass 内での this の参照先が SubClass のインスタンス (SubClass 内での this) ではなくなってしまうのだ。「Graviness Blog」でのやり方では SubClass.prototype 、「JavaScriptっぽい。」でのやり方では SuperClass.prototype になってしまう。つまり SuperClass 内で this にセットした値は SubClass のインスタンス間で共有されるということだ。

例えば以下のようにすると okaka の名前が変わってしまう。これはちょっとまずいと思う。

// Graviness Blog
function inherit(subClass, superClass) {
  var Temp = new Function();
  Temp.prototype = superClass.prototype;
  subClass.prototype = new Temp;
  subClass.prototype.__super__ = superClass;
  subClass.prototype.constructor = subClass;
}

function Animal(name) {
  this.name = name;
}

function Cat(name, coat) {
  Cat.prototype.__super__(name);
  this.coat = coat;
}

inherit(Cat, Animal);

var okaka = new Cat("Okaka", "calico");
alert(okaka.name); // "Okaka"
var shiro = new Cat("Shiro", "white");
alert(okaka.name); // "Shiro"
// JavaScriptっぽい。
function inherit(subClass, superClass) {
  var Temp = new Function();
  Temp.prototype = superClass.prototype;
  subClass.prototype = new Temp;
  subClass.prototype.constructor = subClass;
  subClass.prototype.superclass = superClass.prototype;
}

function Animal(name) {
  this.name = name;
}

function Cat(name, coat) {
  this.superclass.constructor(name);
  this.coat = coat;
}

inherit(Cat, Animal);

var okaka = new Cat("Okaka", "calico");
alert(okaka.name); // "Okaka"
var shiro = new Cat("Shiro", "white");
alert(okaka.name); // "Shiro"

コメント

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※投稿には管理者が設定した質問に答える必要があります。

名前:
メールアドレス:
URL:
次の質問に答えてください:
「ハイパーテキストマークアップ言語」をアルファベット4文字でいうと?

コメント:

トラックバック

このエントリのトラックバックURL: http://nanto.asablo.jp/blog/2005/12/09/171204/tb