Why do the following two lines return different results?
("test" instanceof String) // returns false
("test".constructor == String) // returns true
Tested in the console of chrome version 28.0.1500.95 m
Does it work slightly differently for native types?
constructor
is just a property of the internal [[prototype]]
property, that can easily be manipulated:
function A(){}
function B(){}
A.prototype.constructor = B;
var a = new A();
console.log(a.constructor); //B
The instanceof
operator however checks the internal prototype chain and is not so easily to be fooled, even if you change the complete prototype
property of the constructor function:
function A(){}
function B(){}
A.prototype = B.prototype;
var a = new A();
console.log(a instanceof A); //true
console.log(a instanceof B); //false
So, why is "test" instanceof String === false
but ("test".constructor == String) === true
?
First of all, "test"
is a primitive and primitives are never an instance of anything. What actually happens when you use instanceof
is that the internal [[HasInstance]]
method of the constructor is called with the possible instance as an argument. So a instanceof A
translates roughly to:
`A.[[HasInstance]](a)`
The ECMA Specs have this to say to [[HasInstance]]
: http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5.3
[[HasInstance]] (V)
Assume F is a Function object.
When the [[HasInstance]] internal method of F is called with value V, the following steps are taken:
- If V is not an object, return false.
- ....
In other words: If the left hand side of instanceof
is not an object, the operator will return false.
("test".constructor == String) === true
works for a different reason: If you try to access a property of a primitive, the primitive will be temporarily converted into an object. So "test".constructor
is roughly equal to:
(new String("test")).constructor
in which case you are actually creating an object, with a constructor function and requesting the constructor
property afterward. So it is no surprise, that it will return String
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With