3

Result次のコードでなぜが間違っているのか理解するのに少し問題があります。

サイズを持つ必要があるライブラリ内の他のオブジェクトは、サイズパラメータがのインスタンスであるかどうかをチェックしますInterfaceKit.Core.Size。現在、instanceoffalseを返しています。

var InterfaceKit = {
    Core : {
        Size: function( i_Width, i_Height ){
            Object.defineProperties(this, {
                m_Width : {
                    value: Number( i_Width ) ? Number( i_Width ) : 0
                    , writable: true
                }
                , m_Height : {
                    value: Number( i_Height ) ? Number( i_Height ) : 0
                    , writable: true
                }

            }); 

            this.__proto__ = {
                SetWidth: function( i_Width ){
                    if( Number( i_Width ) )
                        this.m_Width = Number( i_Width ); 

                }
                , GetWidth: function(){
                    return this.m_Width; 
                }
                , SetHeight: function( i_Height ){
                    if( Number( i_Height ) )
                        this.m_Height = Number( i_Height ); 

                }
                , GetHeight: function(){
                    return this.m_Height; 
                }

            };

            this.__proto__.constructor = InterfaceKit.Core.Size; 

        }

    }

}; 

var Result = (new InterfaceKit.Core.Size( 10, 10 ) instanceof InterfaceKit.Core.Size); //false
4

3 に答える 3

2

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/instanceof

instanceofオペレーターは、オブジェクトのチェーンにコンストラクターのプロトタイププロパティがあるかどうかをテストしますprototype

言い換えると...

// an objects prototype chains has this as the root
object.__proto__ // set to: {}

// the prototype property of the constructor
A.B.prototype // unmodified prototype, some object set by JS engine. Probably: {}

// Equivalent objects are not equal, because they are different objects
{} === {} // false

したがって、コンストラクターのプロトタイプは、オブジェクトのプロトタイプチェーンに含まれていません。つまり、コンストラクターがそのオブジェクトを「構築」したとしても、それはコンストラクターではありません。instanceof


しかし、実際には、を使用しないでください__proto__

var A = {
    B: function() {}
};
A.B.prototype = {};

var Result = (new A.B() instanceof A.B); // true
于 2012-12-28T20:17:10.383 に答える
1

ECMAScript仕様から:

11.8.6instanceof演算子

ShiftExpressionのプロダクションRelationalExpression:RelationalExpressionインスタンスは、次のように評価されます。

  1. lrefをRelationalExpressionの評価結果とします。
  2. lvalをGetValue(lref)とします。
  3. ShiftExpressionを評価した結果をrrefとします。
  4. rvalをGetValue(rref)とします。
  5. Type(rval)がObjectでない場合は、TypeError例外をスローします。
  6. rvalに[[HasInstance]]内部メソッドがない場合は、TypeError例外をスローします。
  7. 引数lvalを指定してrvalの[[HasInstance]]内部メソッドを呼び出した結果を返します。

..。

15.3.5.3 [[HasInstance]](V)

FがFunctionオブジェクトであると仮定します。

Fの[[HasInstance]]内部メソッドが値Vで呼び出されると、次の手順が実行されます。

  1. Vがオブジェクトでない場合は、falseを返します。
  2. プロパティ名「prototype」でFの[[Get]]内部メソッドを呼び出した結果をOとします。
  3. Type(O)がObjectでない場合は、TypeError例外をスローします。
  4. 繰り返す
    • VをVの[[Prototype]]内部プロパティの値とします。
    • Vがnullの場合、falseを返します。
    • OとVが同じオブジェクトを参照している場合は、trueを返します。

注Function.prototype.bindを使用して作成された関数オブジェクトには、15.3.4.5.3で定義されている[[HasInstance]]の異なる実装があります。

基本的に、左側のオペランドの継承チェーンに右側のオペランドのプロトタイプがある場合にinstanceof返されます。truel.__proto__ === r.prototype || l.__proto__.__proto__ === r.prototype || ...

オブジェクトの左側のオペランドにはプロトタイプがオーバーライドされており(__proto__内部プロパティの独自のエイリアスです[[prototype]])、Javascriptによって割り当てられていないため、通常のようにnew A.B()から継承しなくなりA.B.prototype、したがって、instanceof A.B

于 2012-12-28T20:20:41.330 に答える
0

私はこれが最良の解決策であることを発見しました:

var InterfaceKit {
    Core: {
        Size : function( i_Width, i_Height ){
            this.__prototype__ = Object.getPrototypeOf( this ); 

            var m_Width  = 0; 
            var m_Height = 0; 

            this.__prototype__.SetWidth  = function( i_Width ){}; 
            this.__prototype__.GetWidth  = function(){}; 
            this.__prototype__.SetHeight = function( i_Height ){}; 
            this.__prototype__.GetHeight = function(){}; 

            {
                 this.SetWidth( i_Width ); 
                 this.SetHeight( i_Height ); 
            }

        }

    }

}; 

var Result = (new InterfaceKit.Core.Size( 10, 10 ) instanceof InterfaceKit.Core.Size); // true
于 2012-12-31T13:54:33.770 に答える