Coder Perfect

In JavaScript, what is the instanceof operator?

Problem

When initially encountered, the instanceof keyword in JavaScript might be perplexing, as many people believe JavaScript is not an object-oriented programming language.

Asked by Alon Gubkin

Solution #1

The actual object being tested to the Right Hand Side (RHS) operand, which is the actual constructor of a class, is the Left Hand Side (LHS) operand. The basic definition is as follows:

Here are some interesting examples, including one straight from Mozilla’s developer site:

var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral"; //no type specified
color2 instanceof String; // returns false (color2 is not a String object)

It’s worth noting that if the object inherits from the class’s prototype, instanceof evaluates to true:

var p = new Person("Jon");
p instanceof Person

Because p inherits from Person.prototype, p instanceof Person is true.

A variable’s type is specified when it is declared.

For instance:

int i;
float f;
Customer c;

The variables I f, and c are shown in the example above. Integer, float, and a user-defined Customer data type are the available options. Types like the ones listed above can be used in any language, not just JavaScript. When declaring a variable in JavaScript, however, you don’t have to provide a type; for example, var x may be a number, a text, or a user-defined data type. So, if we take the Customer object from above, instanceof checks to see if it is of the type supplied, so we might do:

var c = new Customer();
c instanceof Customer; //Returns true as c is just a customer
c instanceof String; //Returns false as c is not a string, it's a customer silly!

We saw that c was declared with the type Customer earlier. We’ve freshened it up and double-checked if it’s of the Customer kind or not. It certainly is, as it returns true. The Customer object is then checked again to see if it is a String. No, we didn’t create a String object; instead, we created a Customer object. It returns false in this scenario.

That’s all there is to it!

Answered by JonH

Solution #2

There’s one aspect of instanceof that hasn’t been mentioned in any of the comments so far: inheritance. Because of prototypal inheritance, a variable evaluated with instanceof could return true for many “types.”

Let’s define a type and a subtype, for example:

function Foo(){ //a Foo constructor
    //assign some props
    return this;
}

function SubFoo(){ //a SubFoo constructor
    Foo.call( this ); //inherit static props
    //assign some new props
    return this;
}

SubFoo.prototype = Object.create(Foo.prototype); // Inherit prototype
SubFoo.prototype.constructor = SubFoo;

Let’s make some instances and see what they’re instances of now that we’ve got a few of “classes”:

var 
    foo = new Foo()
,   subfoo = new SubFoo()
;

alert( 
    "Q: Is foo an instance of Foo? "
+   "A: " + ( foo instanceof Foo ) 
); // -> true

alert( 
    "Q: Is foo an instance of SubFoo? " 
+   "A: " + ( foo instanceof SubFoo ) 
); // -> false

alert( 
    "Q: Is subfoo an instance of Foo? "
+   "A: " + ( subfoo instanceof Foo ) 
); // -> true

alert( 
    "Q: Is subfoo an instance of SubFoo? "
+   "A: " + ( subfoo instanceof SubFoo ) 
); // -> true

alert( 
    "Q: Is subfoo an instance of Object? "
+   "A: " + ( subfoo instanceof Object ) 
); // -> true

Have you noticed the last line? All “new” calls to a function produce an object that is an Object descendant. This is true even when using the shortcut for object creation:

alert( 
    "Q: Is {} an instance of Object? "
+   "A: " + ( {} instanceof Object ) 
); // -> true

What about the definitions of “classes” themselves? What exactly are these examples of?

alert( 
    "Q: Is Foo an instance of Object? "
+   "A:" + ( Foo instanceof Object) 
); // -> true

alert( 
    "Q: Is Foo an instance of Function? "
+   "A:" + ( Foo instanceof Function) 
); // -> true

Understanding that every object can be an instance of MULTIPLE kinds is crucial, because you might (incorrectly) believe that using instanceof, you can tell the difference between, example, an object and a function. A function is an object, as this last example plainly demonstrates.

This is especially critical if you’re utilizing inheritance patterns and want to use methods other than duck-typing to confirm an object’s progeny.

I hope this information is useful to anyone looking into instanceof.

Answered by webnesto

Solution #3

The other answers are correct, but they don’t go into detail on how instanceof works, which would be of interest to language lawyers.

In JavaScript, every object has a prototype, which can be accessed using the __proto__ property. A prototype attribute exists in functions, which is the initial __proto__ for any objects produced by them. When a function is created, it is given a unique object for prototype. The instanceof operator uses this uniqueness to give you an answer. Here’s what instanceof might look like if you wrote it as a function.

function instance_of(V, F) {
  var O = F.prototype;
  V = V.__proto__;
  while (true) {
    if (V === null)
      return false;
    if (O === V)
      return true;
    V = V.__proto__;
  }
}

This is essentially a paraphrase of section 15.3.5.3 of ECMA-262 edition 5.1 (also known as ES5).

You can reassign any object to the prototype property of a function, and you can reassign an object’s __proto__ property after it has been constructed. This will yield the following results:

function F() { }
function G() { }
var p = {};
F.prototype = p;
G.prototype = p;
var f = new F();
var g = new G();

f instanceof F;   // returns true
f instanceof G;   // returns true
g instanceof F;   // returns true
g instanceof G;   // returns true

F.prototype = {};
f instanceof F;   // returns false
g.__proto__ = {};
g instanceof G;   // returns false

Answered by Jay Conrod

Solution #4

It’s worth mentioning that the inclusion of the “new” keyword when declaring the object defines instanceof. In the case of JonH’s example;

var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)

What he didn’t say was this:

var color1 = String("green");
color1 instanceof String; // returns false

Instead of just setting the color1 var to the return value, specifying “new” copied the end state of the String constructor function into it. This, I believe, better demonstrates what the new keyword accomplishes;

function Test(name){
    this.test = function(){
        return 'This will only work through the "new" keyword.';
    }
    return name;
}

var test = new Test('test');
test.test(); // returns 'This will only work through the "new" keyword.'
test // returns the instance object of the Test() function.

var test = Test('test');
test.test(); // throws TypeError: Object #<Test> has no method 'test'
test // returns 'test'

When “new” is used, the value of “this” inside the function is assigned to the declared var, however when it is not used, the return value is assigned instead.

Answered by Stephen Belanger

Solution #5

And you can use it for error handling and debugging, like this:

try{
    somefunction();
} 
catch(error){
    if (error instanceof TypeError) {
        // Handle type Error
    } else if (error instanceof ReferenceError) {
        // Handle ReferenceError
    } else {
        // Handle all other error types
    }
}

Answered by Tarek Saied

Post is based on https://stackoverflow.com/questions/2449254/what-is-the-instanceof-operator-in-javascript