Introduction to instanceof operator
In JavaScript, judging the type of a variable, you will use the typeof operator. When using the typeof operator, you will have a problem using a reference type to store the value. No matter what type of object is referenced, it will return "object". ECMAScript introduces another Java operator instanceof to solve this problem. The instanceof operator is similar to the typeof operator and is used to identify the type of the object being processed. Unlike the typeof method, the instanceof method requires the developer to explicitly confirm that the object is a specific type. For example:
Listing 1. instanceof example
var oStringObject = new String("hello world"); console.log(oStringObject instanceof String); // Output "true"This code asks "Is the variable oStringObject an instance of the String object?" oStringObject is indeed an instance of the String object, so the result is "true". Although not as flexible as the typeof method, the instanceof method is useful when the typeof method returns "object".
General usage of the instanceof operator:
Generally speaking, using instanceof is to determine whether an instance belongs to a certain type. For example:
Listing 2. General usage of instanceof
// Determine whether foo is an instance of Foo class function Foo(){} var foo = new Foo(); console.log(foo instanceof Foo)//trueIn addition, a more heavier point is that instanceof can be used in inheritance relationships to determine whether an instance belongs to its parent type. For example:
Listing 3. Usage of instanceof in inheritance relationships
// Determine whether foo is an instance of Foo class and whether it is an instance of its parent type function Aoo(){} function Foo(){} Foo.prototype = new Aoo();//JavaScript prototype inheritance var foo = new Foo(); console.log(foo instanceof Foo)//true console.log(foo instanceof Aoo)//trueIn the above code, the parent class in a layer of inheritance relationship is judged. In multi-layer inheritance relationship, the instanceof operator is also applicable.
Do you really understand the instanceof operator?
After reading the above code example, do you think the instanceof operator is very simple? Let’s take a look at some complicated usage.
Listing 4. instanceof complex usage
console.log(Object instanceof Object);//true console.log(Function instanceof Function);//true console.log(Number instanceof Number);//false console.log(String instanceof String);//false console.log(Function instanceof Object);//true console.log(Foo instanceof Function);//true console.log(Foo instanceof Foo);//false
Are you confused again after reading the above code? Why do Object and Function instanceof themselves equal true, while other instanceof themselves are not equal true? How to explain it? To fundamentally understand the mystery of instanceof, we need to start from two aspects: 1. How to define this operator in the language specification. 2. JavaScript prototype inheritance mechanism.
Listing 5. JavaScript instanceof operator code
function instance_of(L, R) {//L represents the left expression, R represents the right expression var O = R.prototype;// Take the display prototype of R L = L.__proto__;// Take the implicit prototype of L while (true) { if (L === null) return false; if (O === L)// Here's the point: When O is strictly equal to L, return true; L = L.__proto__; } }Listing 6. Object instanceof Object
// For the sake of convenience of expression, first distinguish between the left expression and the right expression ObjectL = Object, ObjectR = Object; // The following is to gradually deduce O = ObjectR.prototype = Object.prototype L = ObjectL.__proto__ = Function.prototype // The first judgment is O != L // Loop to find whether L still has __proto__ L = Function.prototype.__proto__ = Object.prototype // The second judgment O == L // Return true
Listing 7. Function instanceof Function
// For the sake of convenience of expression, first distinguish between the left expression and the right expression FunctionL = Function, FunctionR = Function; // The following is to gradually deduce O = FunctionR.prototype = Function.prototype L = FunctionL.__proto__ = Function.prototype // The first judgment O == L // Return true
Listing 8. Foo instance of Foo
// For the sake of convenience of expression, first distinguish between the left expression and the right expression FooL = Foo, FooR = Foo; // The following is to gradually deduce according to the specifications O = FooR.prototype = Foo.prototype L = FooL.__proto__ = Function.prototype // The first judgment is O != L // The first judgment is O != L // The cycle is to find whether L still has __proto__ L = Function.prototype.__proto__ = Object.prototype // The second judgment is O != L // The cycle is to find whether L still has __proto__ L = Object.prototype.__proto__ = null // The third judgment L == null // Return false
Briefly analyze the application of instanceof in Dojo inheritance mechanism
In JavaScript, there is no concept of multiple inheritance, just like Java. However, when declaring classes in Dojo, inheritance from multiple classes is allowed. Let’s take Dojo 1.6.1 as an example.
Listing 9. Multiple Inheritance in Dojo
dojo.declare("Aoo",null,{}); dojo.declare("Boo",null,{}); dojo.declare("Foo",[Aoo,Boo],{}); var foo = new Foo(); console.log(foo instanceof Aoo);//true console.log(foo instanceof Boo);//false console.log(foo.isInstanceOf(Aoo));//true console.log(foo.isInstanceOf(Boo));//true console.log(foo.isInstanceOf(Boo));//trueIn the example above, Foo inherits from both Aoo and Boo, but when using the instanceof operator to check whether foo is an instance of Boo, it returns false. In fact, inside Dojo, Foo still inherits only from Aoo, and uses the mixin mechanism to copy the methods and properties in the Boo class to Foo. Therefore, when the instanceof operator is used to check whether it is an instance of Boo, false will be returned. So Dojo adds a new method called isInstanceOf for each class instance, and uses this method to check multiple inheritances.