Is a instanceof b
ALWAYS the same as b.prototype.isPrototypeOf(a)
?
No, a instanceof b
will not always behave the same as b.prototype.isPrototypeOf(a)
.
CMS' answer pointed out that they differ in what they are (one is an operator and the other is a built-in method available on the Object.prototype
object). This is correct, however there are also some special cases for which a instanceof b
will result in a TypeError
while b.prototype.isPrototypeOf(a)
will work just fine and vice versa.
Difference #1
The right-hand side of instanceof
is expected to be a constructor function.
If b
is not a function:
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
Difference #2
When using b.prototype.isPrototypeOf(a)
, b.prototype
should be inheriting from Object.prototype
:
If b.prototype
has not access to the Object.prototype.isPrototypeOf()
method:
b.prototype.isPrototypeOf(a)
will result in a TypeError
.
a instanceof b
will work just fine.
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
Difference #3
If the right-hand side of instanceof
is a bound function, it is treated equivalently to its target function.
If b is a bound function:
a instanceof b
will work just fine.
b.prototype.isPrototypeOf(a)
will result in a TypeError
(bound functions don't have a prototype
property).
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
Conclusion
- If you are dealing with prototypal inheritance established through
Object.create()
, without the use of constructors, you should probably be using the Object.prototype.isPrototypeOf()
method (indeed the use cases of instanceof
are more restricted in that instanceof
expects its right-hand side parameter to be a constructor function).
- If you are dealing with constructors you will be slightly safer by using the
instanceof
operator (you will be able to cover bound functions as well as the cases where Object.prototype
does not lie in the prototype chain of Constructor.prototype
).