Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between using instanceof and checking the constructor?

Tags:

javascript

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?

like image 804
Ally Avatar asked Aug 05 '13 10:08

Ally


1 Answers

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:

  1. If V is not an object, return false.
  2. ....

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.

like image 152
basilikum Avatar answered Sep 28 '22 08:09

basilikum