ChatGPT解决这个技术问题 Extra ChatGPT

What is the instanceof operator in JavaScript?

The instanceof keyword in JavaScript can be quite confusing when it is first encountered, as people tend to think that JavaScript is not an object-oriented programming language.

What is it?

What problems does it solve?

When is it appropriate and when not?

Though the answers bellow are very useful, you don't use it much (at least I don't) in real word applications. One would make a object.type property that holds a string and checks on it.
JS makes no sense whatsoever: "foo" instanceof String => false, 1 instanceof Number => false, {} instanceof Object => false. Say what?!
@morbusg your comment is misleading. First "foo" instanceof String => false is correct, because typeof "foo" == 'string'. new String("foo") instanceof String => true, because typeof String == 'function' - you should treat function like class (definition of class). Variable become instanceof some function (class) when you assign it as var v = new AnythingWhatTypeofEqualsFunction(). The same applies to 1. typeof 1 == 'number' - 'number' is not 'function' :) Next - {} instanceof Object is TRUE in node and modern browsers
@fider: That was commentary towards the language spec, coming from a rubyist.
@morbusg - ({}) instanceof Object will return true. In fact the code you wrote will give you an error.

V
VLAZ

instanceof

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

Checks the current object and returns true if the object is of the specified object type.

Here are some good examples and here is an example taken directly 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)

One thing worth mentioning is instanceof evaluates to true if the object inherits from the class's prototype:

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

That is p instanceof Person is true since p inherits from Person.prototype.

Per the OP's request

When you declare a variable you give it a specific type.

For instance:

int i;
float f;
Customer c;

The above show you some variables, namely i, f, and c. The types are integer, float and a user defined Customer data type. Types such as the above could be for any language, not just JavaScript. However, with JavaScript when you declare a variable you don't explicitly define a type, var x, x could be a number / string / a user defined data type. So what instanceof does is it checks the object to see if it is of the type specified so from above taking the Customer object we could 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!

Above we've seen that c was declared with the type Customer. We've new'd it and checked whether it is of type Customer or not. Sure is, it returns true. Then still using the Customer object we check if it is a String. Nope, definitely not a String we newed a Customer object not a String object. In this case, it returns false.

It really is that simple!


@Alon - I added an example for you. See above, color1 is of type string, so when you say color1 instanceof String; this will return true because color1 is a string.
@Alon - It checks an object to see what type of object it is. Consider a person / customer object. So person p = new person() p is now a person type and not a string type.
In JavaScript, it might be tricky to understand that a variable has the flexibility to have a different type throughout its life span. Code example: jsfiddle.net/sikusikucom/znSPv
@Siku-Siku.Com - I don't see any trick to it var zero = 0; alert(zero); zero = "0"; alert(zero) we went from a primitive int to a primitive string without any issues.
Oh, I meant that it was tricky / new to understand (not do) that "flexibility" in JavaScript, esp. for some who are used to a language that requires e.g. explicit casting to alter a variable type. As you pointed out, it's very easy to change the type from e.g. primitive int to primitive string.
a
adiga

There's an important facet to instanceof that does not seem to be covered in any of the comments thus far: inheritance. A variable being evaluated by use of instanceof could return true for multiple "types" due to prototypal inheritance.

For example, let's define a type and a subtype:

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;

Now that we have a couple of "classes" lets make some instances, and find out what they're instances of:

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

See that last line? All "new" calls to a function return an object that inherits from Object. This holds true even when using object creation shorthand:

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

And what about the "class" definitions themselves? What are they instances 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

I feel that understanding that any object can be an instance of MULTIPLE types is important, since you my (incorrectly) assume that you could differentiate between, say and object and a function by use of instanceof. As this last example clearly shows a function is an object.

This is also important if you are using any inheritance patterns and want to confirm the progeny of an object by methods other than duck-typing.

Hope that helps anyone exploring instanceof.


Even more awesome is that after you inherit from the prototype with SubFoo.prototype = new Foo(); you can add more methods to it, and the subfoo instanceof Foo check will still pass as well as subfoo instanceof SubFoo
J
Jay Conrod

The other answers here are correct, but they don't get into how instanceof actually works, which may be of interest to some language lawyers out there.

Every object in JavaScript has a prototype, accessible through the __proto__ property. Functions also have a prototype property, which is the initial __proto__ for any objects created 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 basically paraphrasing ECMA-262 edition 5.1 (also known as ES5), section 15.3.5.3.

Note that you can reassign any object to a function's prototype property, and you can reassign an object's __proto__ property after it is constructed. This will give you some interesting 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

It is worth noting that the direct manipulation of the "__proto__" property is not allowed in IE. If I recall correctly, direct manipulation of the property is not included in the ECMA spec either so it's probably a bad idea to use it for assignment other than in academic pursuits.
@webnesto, that's true, proto is not in the spec. I didn't know IE didn't support it though. When you say direct manipulation, do you mean it is not exposed to JS code at all, or it's just not Writable?
Not 100% sure on older versions. Sounds like from here (stackoverflow.com/questions/8413505/proto-for-ie9-or-ie10) that in IE9 it is at least readable (though not mutable). Also noteworthy that it sounds like browsers may be dropping it entirely.
Understanding the implied existence of the proto property is important whether it is accessible to user code or not. +10 if I could for citing the spec, this is exactly what I came here looking for.
In order to get the prototype link, use Object.getPrototypeOf(o), this will be the same as the __proto__you describe, but conforms to ECMAScript.
S
Stephen Belanger

I think it's worth noting that instanceof is defined by the use of the "new" keyword when declaring the object. In the example from JonH;

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 mention is this;

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

Specifying "new" actually copied the end state of the String constructor function into the color1 var, rather than just setting it to the return value. I think this better shows what the new keyword does;

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'

Using "new" assigns the value of "this" inside the function to the declared var, while not using it assigns the return value instead.


It doesn't make sense to use new with any of JavaScript's types which makes the accepted answer much more confusing to beginners. text = String('test') and options = {} aren't going to tested by instanceof but, rather, with typeof instead.
Date.getTime() // fail. yes, new is important.
Try running that in a console. You'll get an error because getTime() doesn't exist. You DO need to use new.
P
Peter Mortensen

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
    }
}

W
Willem van der Veen

What is it?

Javascript is a prototypal language which means it uses prototypes for 'inheritance'. the instanceof operator tests if a constructor function's prototype propertype is present in the __proto__ chain of an object. This means that it will do the following (assuming that testObj is a function object):

obj instanceof testObj;

Check if prototype of the object is equal to the prototype of the constructor: obj.__proto__ === testObj.prototype >> if this is true instanceof will return true. Will climb up the prototype chain. For example: obj.__proto__.__proto__ === testObj.prototype >> if this is true instanceof will return true. Will repeat step 2 until the full prototype of object is inspected. If nowhere on the prototype chain of the object is matched with testObj.prototype then instanceof operator will return false.

Example:

function Person(name) { this.name = name; } var me = new Person('Willem'); console.log(me instanceof Person); // true // because: me.__proto__ === Person.prototype // evaluates true console.log(me instanceof Object); // true // because: me.__proto__.__proto__ === Object.prototype // evaluates true console.log(me instanceof Array); // false // because: Array is nowhere on the prototype chain

What problems does it solve?

It solved the problem of conveniently checking if an object derives from a certain prototype. For example, when a function recieves an object which can have various prototypes. Then, before using methods from the prototype chain, we can use the instanceof operator to check whether the these methods are on the object.

Example:

function Person1 (name) { this.name = name; } function Person2 (name) { this.name = name; } Person1.prototype.talkP1 = function () { console.log('Person 1 talking'); } Person2.prototype.talkP2 = function () { console.log('Person 2 talking'); } function talk (person) { if (person instanceof Person1) { person.talkP1(); } if (person instanceof Person2) { person.talkP2(); } } const pers1 = new Person1 ('p1'); const pers2 = new Person2 ('p2'); talk(pers1); talk(pers2);

Here in the talk() function first is checked if the prototype is located on the object. After this the appropriate method is picked to execute. Not doing this check could result in executing a method which doesn't exist and thus a reference error.

When is it appropriate and when not?

We kind of already went over this. Use it when you are in need of checking the prototype of an object before doing something with it.


I think you wanted to write something else than "the prototype of a constructor function appears somewhere in the prototype property of a constructor"
You might want to mention that it would be more appropriate to have the persons share an interface and name both of those methods PersonX.prototype.talk, so that the talk function could simply do person.talk().
You were completely right updated it, so the definition is better. Thanks for pointing out!
Also, don't use __proto__ in documentation, it's deprecated - write Object.getPrototype() instead
y
yfeldblum
//Vehicle is a function. But by naming conventions
//(first letter is uppercase), it is also an object
//constructor function ("class").
function Vehicle(numWheels) {
    this.numWheels = numWheels;
}

//We can create new instances and check their types.
myRoadster = new Vehicle(4);
alert(myRoadster instanceof Vehicle);

A
Andrew Magee

On the question "When is it appropriate and when not?", my 2 cents:

instanceof is rarely useful in production code, but useful in tests where you want to assert that your code returns / creates objects of the correct types. By being explicit about the kinds of objects your code is returning / creating, your tests become more powerful as a tool for understanding and documenting your code.


j
jussty

I just found a real-world application and will use it more often now, I think.

If you use jQuery events, sometimes you want to write a more generic function which may also be called directly (without event). You can use instanceof to check if the first parameter of your function is an instance of jQuery.Event and react appropriately.

var myFunction = function (el) {                
    if (el instanceof $.Event) 
        // event specific code
    else
        // generic code
};

$('button').click(recalc);    // Will execute event specific code
recalc('myParameter');  // Will execute generic code

In my case, the function needed to calculate something either for all (via click event on a button) or only one specific element. The code I used:

var recalc = function (el) { 
    el = (el == undefined || el instanceof $.Event) ? $('span.allItems') : $(el);
    // calculate...
};

佚名

instanceof is just syntactic sugar for isPrototypeOf:

function Ctor() {}
var o = new Ctor();

o instanceof Ctor; // true
Ctor.prototype.isPrototypeOf(o); // true

o instanceof Ctor === Ctor.prototype.isPrototypeOf(o); // equivalent

instanceof just depends on the prototype of a constructor of an object.

A constructor is just a normal function. Strictly speaking it is a function object, since everything is an object in Javascript. And this function object has a prototype, because every function has a prototype.

A prototype is just a normal object, which is located within the prototype chain of another object. That means being in the prototype chain of another object makes an object to a prototype:

function f() {} //  ordinary function
var o = {}, // ordinary object
 p;

f.prototype = o; // oops, o is a prototype now
p = new f(); // oops, f is a constructor now

o.isPrototypeOf(p); // true
p instanceof f; // true

The instanceof operator should be avoided because it fakes classes, which do not exist in Javascript. Despite the class keyword not in ES2015 either, since class is again just syntactic sugar for...but that's another story.


The very first line is incorrect! See here for more: "isPrototypeOf() differs from the instanceof operator. In the expression "object instanceof AFunction", the object prototype chain is checked against AFunction.prototype, not against AFunction itself."
@Yan And still instanceof is derived from isPrototypeOf. I call this syntactic sugar. And your MDN source is a joke, isn't it?
No. It isn't and wasn't supposed to be a joke, but still the wrong link. I was meant to have this one posted. I don't want to get into technicalities, but instanceof does not do the same thing as isPrototypeOf. That's it.
"" instanceof object is false, but new String('') instanceof object is true. Everything is not an object in Javascript
f
fider

@SebastianSimon my last answer is 8 years old (when I lamed) and it is possible I wrote some bull*hit :)

Briefly - currently the only cases when I am using instanceof is when I am using class instances and behaviour depends on class I will receive, eg. I want to distinct if 404 is ErrorA(resource not exists) or ErrorB(service not found) - library response codes were confusing but for my luck it throwed using different error classes.

Definitely (currently) I would NOT use it to check types that reflects primitives - you cannot be sure if library is returning 'msg' or new String('msg').

Both of them have methods that belongs to String class because 'msg' primitive is internally wrapped into string object. Internally means by interpreter. They are both Strings but instanceof operator seems to be insufficient here - to check if sth. is primitive or class I would use mix of typeof && instanceof - but only for something returned from external JS library.

Currenlty TypeScript is solving this problem and you no longer have to use such officious checks with typeof and instanceof.