Class Checking "instanceof"
Classes: Class Checking
What is class checking in JavaScript?
View Answer:
Let's say we have a Car class, and we want to confirm if a given object is an instance of Car. Here's how we might perform class checking in JavaScript:
class Car {
constructor(model, year) {
this.model = model;
this.year = year;
}
}
// Create a new instance of Car
let myCar = new Car('Tesla Model 3', 2022);
// Check if myCar is an instance of Car
if (myCar instanceof Car) {
console.log('myCar is an instance of Car');
} else {
console.log('myCar is not an instance of Car');
}
In this example, myCar instanceof Car will return true because myCar was created as an instance of the Car class. So, the output of this code would be "myCar is an instance of Car".
This is a simple form of class checking. It is important to note that JavaScript is a prototype-based language, and class checking can become more complex when inheritance and other advanced features are used. But for most practical purposes, the instanceof operator will serve you well.
What operator is typically used for class checking?
View Answer:
const myArray = [1, 2, 3, 4, 5];
console.log(myArray instanceof Array); // Returns true
What does the instanceof operator do in JavaScript?
View Answer:
class Car {
constructor(model, year) {
this.model = model;
this.year = year;
}
}
class Bike {
constructor(model, year) {
this.model = model;
this.year = year;
}
}
let myCar = new Car('Tesla Model 3', 2022);
let myBike = new Bike('Yamaha MT-15', 2020);
console.log(myCar instanceof Car); // Returns true
console.log(myCar instanceof Bike); // Returns false
console.log(myBike instanceof Car); // Returns false
console.log(myBike instanceof Bike); // Returns true
In this code:
myCar instanceof Carchecks ifmyCaris an instance of theCarclass, and returnstrue.myCar instanceof Bikechecks ifmyCaris an instance of theBikeclass, and returnsfalse.myBike instanceof Carchecks ifmyBikeis an instance of theCarclass, and returnsfalse.myBike instanceof Bikechecks ifmyBikeis an instance of theBikeclass, and returnstrue.
As you can see, instanceof allows you to confirm the class of an object in JavaScript.
Is an Array an instance of an Object in JavaScript?
View Answer:
let myArray = [1, 2, 3, 4, 5];
console.log(myArray instanceof Array); // Returns true
console.log(myArray instanceof Object); // Also returns true
In this code:
myArray instanceof Arraychecks ifmyArrayis an instance of theArrayclass, and returnstrue.myArray instanceof Objectchecks ifmyArrayis an instance of theObjectclass, and also returnstrue.
As you can see, an Array is indeed considered an instance of an Object in JavaScript, due to JavaScript's object-based nature where almost everything is an object.
Is it possible to make a custom obj instanceof Class algorithm?
View Answer:
class MyCustomClass {
static [Symbol.hasInstance](instance) {
return Array.isArray(instance);
}
}
const myArray = [1, 2, 3, 4, 5];
const myObject = {foo: 'bar'};
console.log(myArray instanceof MyCustomClass); // Returns true
console.log(myObject instanceof MyCustomClass); // Returns false
In this code:
- We define a
MyCustomClassclass with aSymbol.hasInstancemethod. - This method checks if the
instanceis an Array using theArray.isArraymethod. myArray instanceof MyCustomClasschecks ifmyArrayis an "instance" ofMyCustomClassas per our custom definition, and returnstruebecausemyArrayis an array.myObject instanceof MyCustomClasschecks ifmyObjectis an "instance" ofMyCustomClassas per our custom definition, and returnsfalsebecausemyObjectis not an array.
So, you can indeed customize the behavior of the instanceof operator in modern JavaScript. Note that this can lead to some surprising results, so use this feature with caution!
Can you explain what happens with an instanceof class check?
View Answer:
class Rabbit extends Animal {}
let rabbit = new Rabbit();
console.log(rabbit instanceof Animal); // true
// rabbit.__proto__ === Rabbit.prototype
// rabbit.__proto__.__proto__ === Animal.prototype (match! return true)
We already know that plain objects are converted to string as [object Object]. Is there a way to create a custom toString result for our custom objects?
View Answer:
let user = {
[Symbol.toStringTag]: 'User',
};
console.log({}.toString.call(user)); // [object User]
// toStringTag for the environment-specific object and class:
console.log(window[Symbol.toStringTag]); // Window
console.log(XMLHttpRequest.prototype[Symbol.toStringTag]); // XMLHttpRequest
console.log({}.toString.call(window)); // [object Window]
console.log({}.toString.call(new XMLHttpRequest())); // [object XMLHttpRequest]
Is typeof operator useful for class checking?
View Answer:
Can you use instanceof with built-in JavaScript classes?
View Answer:
let myDate = new Date();
console.log(myDate instanceof Date); // Returns true
let myArray = [1, 2, 3];
console.log(myArray instanceof Array); // Returns true
What will instanceof return if the object is not of a specific class?
View Answer:
class MyClass {}
let myInstance = new MyClass();
let myNumber = 5;
console.log(myInstance instanceof MyClass); // logs true
console.log(myNumber instanceof MyClass); // logs false
Is instanceof reliable across different windows or frames?
View Answer:
Here's an example that illustrates the potential issue with instanceof across different windows or frames.
// Assume we have two windows or frames: window1 and window2
let array1 = window1.Array;
let array2 = window2.Array;
let instance1 = new array1();
let instance2 = new array2();
console.log(instance1 instanceof array1); // logs true
console.log(instance2 instanceof array1); // logs false even though instance2 is an Array object
In this case, instance2 is an instance of Array, but instanceof returns false because it's from a different window or frame.
What is a drawback of instanceof in Modern JavaScript?
View Answer:
The following example demonstrates this drawback of instanceof. Consider two iframes, each with their own execution environment.
Assume we have two iframes with their separate JavaScript execution contexts:
<iframe id="iframe1" srcdoc="<script>window.onload = function() { parent.array1 = new Array(); };</script>"></iframe>
<iframe id="iframe2" srcdoc="<script>window.onload = function() { parent.array2 = new Array(); };</script>"></iframe>
Then in the parent frame:
window.onload = function() {
console.log(array1 instanceof Array); // logs true
console.log(array2 instanceof Array); // logs true
console.log(array1 instanceof array2.constructor); // logs false
}
In the above code, array1 and array2 are both instances of Array, but array1 instanceof array2.constructor returns false because array1 and array2 were created in different execution contexts (iframes), each with its own Array constructor.
How can you perform class checking across iframes in JavaScript?
View Answer:
Here is a simple code example. Instead of using instanceof, you can use Object.prototype.toString.call() to perform class checking across iframes:
<iframe id="iframe1" srcdoc="<script>window.onload = function() { parent.arrayFromIframe = new Array(); };</script>"></iframe>
<script>
window.onload = function() {
console.log(Object.prototype.toString.call(arrayFromIframe) === '[object Array]'); // logs true
}
</script>
In the above example, even though arrayFromIframe was created in a different execution context (an iframe), Object.prototype.toString.call(arrayFromIframe) still correctly identifies it as an Array.
What would Object.prototype.toString.call() return for an array?
View Answer:
What is duck typing in JavaScript?
View Answer:
let Duck = function() {};
Duck.prototype.quack = function() {
console.log('Quack!');
};
let NotADuck = function() {};
let duck = new Duck();
let notADuck = new NotADuck();
function makeItQuack(possiblyADuck) {
if (typeof possiblyADuck.quack === 'function') {
possiblyADuck.quack();
} else {
console.log('This is not a duck!');
}
}
makeItQuack(duck); // logs 'Quack!'
makeItQuack(notADuck); // logs 'This is not a duck!'
In this example, we don't care about the type of possiblyADuck. We only care that it has a quack method. This is the essence of duck typing: "If it quacks like a duck, it's a duck."
Can instanceof be used with custom classes?
View Answer:
How does instanceof differ from typeof?
View Answer:
class MyClass {}
let myInstance = new MyClass();
let myNumber = 5;
console.log(myInstance instanceof MyClass); // logs true
console.log(myNumber instanceof MyClass); // logs false
console.log(typeof myInstance); // logs "object"
console.log(typeof myNumber); // logs "number"
Why can't we rely on the constructor property for class checking?
View Answer:
function MyClass() {}
const myInstance = new MyClass();
console.log(myInstance.constructor === MyClass); // true
MyClass.prototype.constructor = null;
console.log(myInstance.constructor === MyClass); // false
const noConstructor = Object.create(null);
console.log(noConstructor.constructor); // undefined
This code demonstrates that relying on the constructor property for class checking can be unreliable.
Can class checking be used to identify null or undefined values?
View Answer:
Does instanceof work with primitive types in JavaScript?
View Answer:
let myString = "Hello, World!";
let myNumber = 42;
console.log(myString instanceof String); // false
console.log(myNumber instanceof Number); // false
In both checks, instanceof returns false because these are not instances of String or Number objects, but primitive string and number types.
Is instanceof always accurate for arrays?
View Answer:
How would you perform class checking for null or undefined?
View Answer:
In JavaScript, you can use a direct comparison for checking null or undefined. Here's an example:
let myNullValue = null;
let myUndefinedValue = undefined;
console.log(myNullValue === null); // true
console.log(myUndefinedValue === undefined); // true
In this code, the === operator accurately checks if myNullValue is null and myUndefinedValue is undefined.