constructor is simply a property of the [[prototype]] internal property that is easy to manipulate:
function A(){} function B(){} A.prototype.constructor = B; var a = new A(); console.log(a.constructor);
However, the instanceof operator checks the inner prototype chain and is not so easy to fool, even if you change the full prototype property of the constructor function:
function A(){} function B(){} A.prototype = B.prototype; var a = new A(); console.log(a instanceof A);
So, why is "test" instanceof String === false , but ("test".constructor == String) === true ?
First of all, "test" is primitive, and primitives are never an example of anything. In fact, when you use instanceof , the constructor's [[HasInstance]] internal method is called with a possible instance as an argument. So, a instanceof A roughly translates:
`A.[[HasInstance]](a)`
ECMA specifications have this meaning to say [[HasInstance]] : http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5.3
[[HasInstance]] (V)
Suppose F is a Function object.
When the [[HasInstance]] F internal method is called with a value of V, the following steps are performed:
- If V is not an object, return false.
- ....
In other words: if the left side of instanceof not an object, the statement will return false.
("test".constructor == String) === true works for another reason: if you try to access the property of the primitive, the primitive will be temporarily converted to an object. So, "test".constructor approximately equal to:
(new String("test")).constructor
in this case, you are actually creating an object with a constructor function and requesting the constructor property. Therefore it is not surprising that it will return String .