2017-04-07 6 views
1
function A(){} 
A.prototype = "Foo bar"; 

new A() instanceof A; 
// TypeError: Function has non-object prototype 'Foo bar' in instanceof check 

ご覧のとおり、コンストラクタのプロトタイプがオブジェクトでない場合、エラーが発生し、エラーがスローされます。 instanceofが失敗しないようにする方法はありますか?"instanceof"が失敗するかどうか確認してください

typeof new A().constructor.prototype === "object" 

typeof Object.getPrototypeOf(new A()) === "object" 

明らかに動作しません。

+2

'try/catch'でラップすることがありますか? – Barmar

+1

A.prototype ===「オブジェクト」の 'typeofについてはどうですか? – Barmar

+0

@Barmar以前はどう思ったのですか?ありがとう。 –

答えて

1

エラーが対象となるA.prototypeニーズを言うので、あなたはそれをチェックする必要があります

function isObject(x) { 
    return x != null && (typeof x == "object" || typeof x == "function"); 
} 

しかしisObject(A.prototype)あなたがinstanceofコールを主張するために行うことができるすべてではありませんスローされません。仕様では、あなたはテストする必要があります

function allowsInstanceCheck(C) { 
    try { 
     if (!isObject(C)) return false; 
     var m = C[Symbol.hasInstance]; 
     if (m != null) return typeof m == "function"; 
     if (typeof C != "function") return false; 
     return isObject(C.prototype); 
    } catch (e) { 
     // any of the property accesses threw 
     return false; 
    } 
} 
1

try/catchを使用してエラーをキャッチします。

function isItA(obj) { 
 
    try { 
 
    return obj instanceof A; 
 
    } catch (e) { 
 
    return false; // 
 
    } 
 
} 
 

 
function A() {} 
 
A.prototype = "Foo bar"; 
 
function B() {} 
 
B.prototype = "Baz Quux"; 
 
console.log(isItA(new A())); 
 
console.log(isItA(new B()));

+0

タイプエラーの望ましくない影響を回避しながら、trueを返すべきときはfalseを返します。 :-( – RobG

+0

オブジェクトに無効なプロトタイプがある場合、実際には 'A'かどうかを判断する方法はありません。デフォルトで' false'を返します。 。 – Barmar

+0

'Foo.prototype'がオブジェクトでない場合、' new Foo() 'によって作成されたオブジェクトはObject.prototypeから継承されますので、Fooのインスタンスが存在しないため、* false *はOKです。方法)。 – RobG

1

おそらく本当に答えは、興味深い結論。 GetPrototypeFromConstructorに記載されているように、そのプロトタイププロパティは、オブジェクトではない場合、この関数は、コンストラクタと呼ばれる

は、新しいインスタンスは、その[[Prototpye]]としてintrinsicDefaultProtoが割り当てられます。新しいインスタンスを作成する過程において

は、intrinsicDefaultProtoは(少なくともFirefoxで)であるように思わfallbackProtoの値、のObject.prototype渡されます。

そしてのObject.prototypeコンストラクタプロパティは、そのインスタンスのconstructorプロパティは、候補オブジェクトはどちらか動作しません参照するかどうかをテストし、オブジェクトであるからです。だから、

function Foo(){} 
 
Foo.prototype = 'A'; 
 
var foo = new Foo(); 
 

 
// foo inherits directly from Object.prototype, not Foo 
 
console.log(Object.getPrototypeOf(foo) == Object.prototype) // true 
 

 
// foo also inherits constructor property from Object.prototype 
 
console.log(foo.constructor == Object) // true

instanceofはは、プログラムの設計や実装でより深刻な問題に可能性の高いポイントを失敗している状況。このようなエラーを隠すことは良い考えではないようです(将来のメンテナが発見するためにトラップをコード内に残すことでない限り)。

関連する問題