1

オブジェクトのメソッドをオーバーライドしようとしていますが、 を使用してプロトタイプの元のメソッドを呼び出しますObject.getPrototypeOf()。これは初めてうまく機能しますが、メソッドが複数回オーバーライドされると問題が発生します。

このコードにより、スタック オーバーフローが発生します。

A =
{
   blurg: function()
   {
      puts('hey there')
   }
}

B = (function buildB(){
   var obj = Object.create(A)

   obj.blurg = function()
   {
      Object.getPrototypeOf(this).blurg.apply(this, arguments)

      puts('hai!!!!')
   }

   return obj
})()

b = (function buildb(){
   var obj = Object.create(B)

   obj.blurg = function()
   {
      Object.getPrototypeOf(this).blurg.apply(this, arguments)

      puts('bye bye')
   }

   return obj
})()


b.blurg()

jsフィドル

問題は、現在のオブジェクトを としてプロトタイプのメソッドを呼び出したいことですthis。これは、そのメソッドが同じことを行うときに問題を引き起こします。

私はこれについて間違った方法で進んでいますか?正しいプロトタイプがプルアップされていることを確認するためのヘルパー関数を作成する方法はありますか? 私は少し途方に暮れています。

4

1 に答える 1

3

問題は、JavaScript では、本質的に、this常にプロトタイプ チェーンのボトム ダウン オブジェクト インスタンスを参照することです。そのため、上記のような階層構造でメソッドをオーバーライドするthis.prototype.someMethod()と、オブジェクト インスタンスの正確な基本クラスを参照しません。階層が最大 2 レベルの場合は問題のようですが、3 レベル以上の階層構造を定義すると、再帰は避けられません。方法は次のとおりです。

A: grand super class
B: super class - inherits from A (B.prototype = A)
C: class - inherits from B (C.prototype = B)

a: instance of A (defines someMethod)
b: instance of B (defines someMethod, calls A.someMethod through Object.getPrototypeOf(this))
c: instance of C (defines someMethod, calls B.someMethod through Object.getPrototypeOf(this))

b.someMethod呼び出されると、A の someMethod を正常に呼び出すことができます ( Object.getPrototypeOf(this)b によって呼び出されると A を返します)。

ただし、c.someMethodが呼び出されると、最初に が呼び出されますb.someMethod。これは、c によって呼び出されたときに常に B を返すb.someMethodためです。Object.getPrototypeOf(this)ここでスタック オーバーフローが発生します。

これを解決するには、新しいサブクラスを定義するたびに基本クラスの参照を保存しthis、スーパークラス メソッドを呼び出すときは使用しないようにします。

A =
{
    blurg: function () {
        console.log('hey there')
    }
};

B = (function buildB() {
    var obj = Object.create(A);
    var base = Object.getPrototypeOf(obj);

    obj.blurg = function () {
        base.blurg.apply(this, arguments);
        console.log('hai!!!!')
    }

    return obj
})();

C = (function buildb() {
    var obj = Object.create(B);
    var base = Object.getPrototypeOf(obj);

    obj.blurg = function () {
        base.blurg.apply(this, arguments);
        console.log('bye bye');
    }

    return obj
})();

C.blurg();
于 2012-05-14T19:04:59.677 に答える