私自身の古いコードのいくつかでは、次のものを使用しています。
_Object.prototype.instanceOf = function( iface )
{
return iface.prototype.isPrototypeOf( this );
};
_
それから私は(例えば)
_[].instanceOf( Array )
_
これは機能しますが、次のように同じように機能します。
_[] instanceof Array
_
さて、確かにこれは非常に単純な例にすぎません。したがって、私の質問は次のとおりです。
_a instanceof b
_ [〜#〜] always [〜#〜]はb.prototype.isPrototypeOf(a)
と同じですか?
はい、どちらも同じことを行います。どちらもプロトタイプチェーンをトラバースして、その中の特定のオブジェクトを探します。
両方の違いは、それらが何であるか、およびそれらをどのように使用するかです。 isPrototypeOf
は_Object.prototype
_オブジェクトで使用可能な関数であり、次のことをテストできます。 特定のオブジェクトは別のプロトタイプチェーンにあります。このメソッドは_Object.prototype
_で定義されているため、すべてのオブジェクトで使用できます。
instanceof
は演算子であり、オブジェクトと コンストラクター関数)の2つのオペランドが必要です。 、渡された関数prototype
プロパティがオブジェクトのチェーンに存在するかどうかをテストします( [[HasInstance]](V)
内部操作を介して、関数オブジェクトでのみ使用可能)。
例えば:
_function A () {
this.a = 1;
}
function B () {
this.b = 2;
}
B.prototype = new A();
B.prototype.constructor = B;
function C () {
this.c = 3;
}
C.prototype = new B();
C.prototype.constructor = C;
var c = new C();
// instanceof expects a constructor function
c instanceof A; // true
c instanceof B; // true
c instanceof C; // true
// isPrototypeOf, can be used on any object
A.prototype.isPrototypeOf(c); // true
B.prototype.isPrototypeOf(c); // true
C.prototype.isPrototypeOf(c); // true
_
a instanceof b
は常にb.prototype.isPrototypeOf(a)
と同じですか?
いいえ、a instanceof b
は常にb.prototype.isPrototypeOf(a)
と同じように動作するとは限りません。
CMSの回答それらが何であるかが異なることを指摘しました(1つは演算子で、もう1つはObject.prototype
オブジェクトで使用可能な組み込みメソッドです)。これは正しいですが、a instanceof b
がTypeError
になり、b.prototype.isPrototypeOf(a)
が正常に機能する、またはその逆の特殊なケースもあります。
instanceof
の右側は、コンストラクター関数であることが期待されています。
b
が関数でない場合:
a instanceof b
はTypeError
になります。
b.prototype.isPrototypeOf(a)
は問題なく動作します。
const b = {
prototype: {}
};
const a = Object.create( b.prototype );
console.log( b.prototype.isPrototypeOf(a) ); // true
console.log( a instanceof b ); // TypeError: Right-hand side of 'instanceof' is not callable
b.prototype.isPrototypeOf(a)
を使用する場合、b.prototype
はObject.prototype
から継承する必要があります。
b.prototype
がObject.prototype.isPrototypeOf()
メソッドにアクセスできない場合:
b.prototype.isPrototypeOf(a)
はTypeError
になります。a instanceof b
は問題なく動作します。function B() {};
B.prototype = Object.create( null );
const a = new B();
console.log( a instanceof B ); // true
console.log( B.prototype.isPrototypeOf(a) ) // TypeError: B.prototype.isPrototypeOf is not a function
instanceof
の右側がバインドされた関数である場合、それはそのターゲット関数と同等に扱われます。
Bがバインドされた関数の場合:
a instanceof b
は問題なく動作します。b.prototype.isPrototypeOf(a)
はTypeError
になります(バインドされた関数にはprototype
プロパティがありません)。function B() {};
const BoundB = B.bind( null );
const a = new B();
console.log( a instanceof BoundB ); // true
console.log( BoundB.prototype.isPrototypeOf(a) ) // TypeError: Cannot read property 'isPrototypeOf' of undefined
Object.create()
を介して確立されたプロトタイプの継承を処理している場合は、おそらくObject.prototype.isPrototypeOf()
メソッドを使用する必要があります(実際、instanceof
のユースケースはinstanceof
は、右側のパラメーターがコンストラクター関数であることを期待しているという点で、より制限されています)。instanceof
演算子を使用することで少し安全になります(バインドされた関数と、Object.prototype
がConstructor.prototype
のプロトタイプチェーンにない場合をカバーできます)。1つは式であり、もう1つはメソッド呼び出しであるため、演算子の優先順位と真実性は異なります。強調すべきことの1つは、両方 プロトタイプチェーンをトラバースする、したがって、一致するプロトタイプと問題のオブジェクトの間に1対1のマッピングがあると想定することはできません。
var i = 0;
function foo()
{
console.log("foo");
console.log(i++ + ": " + Object.prototype.isPrototypeOf(Object) ) //true
console.log(i++ + ": " + Function.prototype.isPrototypeOf(Function) ) //true
console.log(i++ + ": " + Function.prototype.isPrototypeOf(Function) ) //true
console.log(i++ + ": " + Function.prototype.isPrototypeOf(Object) ) //true
console.log(i++ + ": " + RegExp.prototype.isPrototypeOf( RegExp(/foo/) ) ) //true
console.log(i++ + ": " + Object.prototype.isPrototypeOf( RegExp(/foo/) ) ) //true
console.log(i++ + ": " + Function.prototype.isPrototypeOf( RegExp(/foo/) ) ) //false
console.log(i++ + ": " + Object.prototype.isPrototypeOf(Math) ) //true
console.log(i++ + ": " + Math.isPrototypeOf(Math) ) //false
}
function bar()
{
console.log("bar");
console.log(i++ + ": " + (Object instanceof Object) ) //true
console.log(i++ + ": " + (Function instanceof Function) ) //true
console.log(i++ + ": " + (Function instanceof Object) ) //true
console.log(i++ + ": " + (RegExp(/foo/) instanceof RegExp) ) //true
console.log(i++ + ": " + (RegExp(/foo/) instanceof Object) ) //true
console.log(i++ + ": " + (RegExp(/foo/) instanceof Function) ) //false
console.log(i++ + ": " + (Math instanceof Object) ) //true
console.log(i++ + ": " + (Math instanceof Math) ) //error
}
try
{
foo()
}
catch(e)
{
console.log(JSON.stringify(e));
}
finally
{
try
{
bar();
}
catch(e)
{
console.log(JSON.stringify(e));
}
}
参照