instanceof
BaselineWidely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Theinstanceof
operator tests to see if theprototype
property of a constructor appears anywhere in the prototype chain of an object. The return value is a boolean value. Its behavior can be customized withSymbol.hasInstance
.
Try it
function Car(make, model, year) { this.make = make; this.model = model; this.year = year;}const auto = new Car("Honda", "Accord", 1998);console.log(auto instanceof Car);// Expected output: trueconsole.log(auto instanceof Object);// Expected output: true
Syntax
object instanceof constructor
Parameters
object
The object to test.
constructor
Constructor to test against.
Exceptions
TypeError
Thrown if
constructor
is not an object. Ifconstructor
doesn't have a[Symbol.hasInstance]()
method, it must also be a function.
Description
Theinstanceof
operator tests the presence ofconstructor.prototype
inobject
's prototype chain. This usually (thoughnot always) meansobject
was constructed withconstructor
.
// defining constructorsfunction C() {}function D() {}const o = new C();// true, because: Object.getPrototypeOf(o) === C.prototypeo instanceof C;// false, because D.prototype is nowhere in o's prototype chaino instanceof D;o instanceof Object; // true, because:C.prototype instanceof Object; // true// Re-assign `constructor.prototype`: you should// rarely do this in practice.C.prototype = {};const o2 = new C();o2 instanceof C; // true// false, because C.prototype is nowhere in// o's prototype chain anymoreo instanceof C;D.prototype = new C(); // add C to [[Prototype]] linkage of Dconst o3 = new D();o3 instanceof D; // trueo3 instanceof C; // true since C.prototype is now in o3's prototype chain
Note that the value of aninstanceof
test can change ifconstructor.prototype
is re-assigned after creating the object (which is usually discouraged). It can also be changed by changingobject
's prototype usingObject.setPrototypeOf
.
Classes behave in the same way, because classes also have theprototype
property.
class A {}class B extends A {}const o1 = new A();// true, because Object.getPrototypeOf(o1) === A.prototypeo1 instanceof A;// false, because B.prototype is nowhere in o1's prototype chaino1 instanceof B;const o2 = new B();// true, because Object.getPrototypeOf(Object.getPrototypeOf(o2)) === A.prototypeo2 instanceof A;// true, because Object.getPrototypeOf(o2) === B.prototypeo2 instanceof B;
Forbound functions,instanceof
looks up for theprototype
property on the target function, since bound functions don't haveprototype
.
class Base {}const BoundBase = Base.bind(null, 1, 2);console.log(new Base() instanceof BoundBase); // true
instanceof and Symbol.hasInstance
Ifconstructor
has aSymbol.hasInstance
method, the method will be called in priority, withobject
as its only argument andconstructor
asthis
.
// This class allows plain objects to be disguised as this class's instance,// as long as the object has a particular flag as its property.class Forgeable { static isInstanceFlag = Symbol("isInstanceFlag"); static [Symbol.hasInstance](obj) { return Forgeable.isInstanceFlag in obj; }}const obj = { [Forgeable.isInstanceFlag]: true };console.log(obj instanceof Forgeable); // true
Because all functions inherit fromFunction.prototype
by default, most of the time, theFunction.prototype[Symbol.hasInstance]()
method specifies the behavior ofinstanceof
when the right-hand side is a function. See theSymbol.hasInstance
page for the exact algorithm ofinstanceof
.
instanceof and multiple realms
JavaScript execution environments (windows, frames, etc.) are each in their ownrealm. This means that they have different built-ins (different global object, different constructors, etc.). This may result in unexpected results. For instance,[] instanceof window.frames[0].Array
will returnfalse
, becauseArray.prototype !== window.frames[0].Array.prototype
and arrays in the current realm inherit from the former.
This may not make sense at first, but for scripts dealing with multiple frames or windows, and passing objects from one context to another via functions, this will be a valid and strong issue. For instance, you can securely check if a given object is in fact an Array usingArray.isArray()
, neglecting which realm it comes from.
For example, to check if aNode
is anSVGElement
in a different context, you can usemyNode instanceof myNode.ownerDocument.defaultView.SVGElement
.
Examples
Using instanceof with String
The following example shows the behavior ofinstanceof
withString
objects.
const literalString = "This is a literal string";const stringObject = new String("String created with constructor");literalString instanceof String; // false, string primitive is not a StringstringObject instanceof String; // trueliteralString instanceof Object; // false, string primitive is not an ObjectstringObject instanceof Object; // truestringObject instanceof Date; // false
Using instanceof with Map
The following example shows the behavior ofinstanceof
withMap
objects.
const myMap = new Map();myMap instanceof Map; // truemyMap instanceof Object; // truemyMap instanceof String; // false
Objects created using Object.create()
The following example shows the behavior ofinstanceof
with objects created usingObject.create()
.
function Shape() {}function Rectangle() { Shape.call(this); // call super constructor.}Rectangle.prototype = Object.create(Shape.prototype);Rectangle.prototype.constructor = Rectangle;const rect = new Rectangle();rect instanceof Object; // truerect instanceof Shape; // truerect instanceof Rectangle; // truerect instanceof String; // falseconst literalObject = {};const nullObject = Object.create(null);nullObject.name = "My object";literalObject instanceof Object; // true, every object literal has Object.prototype as prototype({}) instanceof Object; // true, same case as abovenullObject instanceof Object; // false, prototype is end of prototype chain (null)
Demonstrating that myCar is of type Car and type Object
The following code creates an object typeCar
and an instance of that object type,myCar
. Theinstanceof
operator demonstrates that themyCar
object is of typeCar
and of typeObject
.
function Car(make, model, year) { this.make = make; this.model = model; this.year = year;}const myCar = new Car("Honda", "Accord", 1998);const a = myCar instanceof Car; // returns trueconst b = myCar instanceof Object; // returns true
Not an instanceof
To test if an object is not aninstanceof
a specific constructor, you can do:
if (!(myCar instanceof Car)) { // Do something, like: // myCar = new Car(myCar)}
This is really different from:
if (!myCar instanceof Car) { // unreachable code}
This will always befalse
. (!myCar
will be evaluated beforeinstanceof
, so you always try to know if a boolean is an instance ofCar
).
Overriding the behavior of instanceof
A common pitfall of usinginstanceof
is believing that, ifx instanceof C
, thenx
was created usingC
as constructor. This is not true, becausex
could be directly assigned withC.prototype
as its prototype. In this case, if your code readsprivate fields ofC
fromx
, it would still fail:
class C { #value = "foo"; static getValue(x) { return x.#value; }}const x = { __proto__: C.prototype };if (x instanceof C) { console.log(C.getValue(x)); // TypeError: Cannot read private member #value from an object whose class did not declare it}
To avoid this, you can override the behavior ofinstanceof
by adding aSymbol.hasInstance
method toC
, so that it does a branded check within
:
class C { #value = "foo"; static [Symbol.hasInstance](x) { return #value in x; } static getValue(x) { return x.#value; }}const x = { __proto__: C.prototype };if (x instanceof C) { // Doesn't run, because x is not a C console.log(C.getValue(x));}
Note that you may want to limit this behavior to the current class; otherwise, it could lead to false positives for subclasses:
class D extends C {}console.log(new C() instanceof D); // true; because D inherits [Symbol.hasInstance] from C
You could do this by checking thatthis
is the current constructor:
class C { #value = "foo"; static [Symbol.hasInstance](x) { return this === C && #value in x; }}class D extends C {}console.log(new C() instanceof D); // falseconsole.log(new C() instanceof C); // trueconsole.log({ __proto__: C.prototype } instanceof C); // false
Specifications
Specification |
---|
ECMAScript® 2026 Language Specification # sec-relational-operators |