instanceof
Baseline Widely 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.
In this article
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: trueSyntax
object instanceof constructorParameters
objectThe object to test.
constructorConstructor to test against.
Exceptions
TypeErrorThrown if
constructoris not an object. Ifconstructordoesn'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 chainNote 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); // trueinstanceof 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); // trueBecause 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; // falseUsing 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; // falseObjects 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 trueNot 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 CYou 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); // falseSpecifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-relational-operators> |