JavaScript instanceof operator in-depth anatomy

Source: Internet
Author: User

Go from: Introduction to https://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/instanceof Operators

In JavaScript, judging the type of a variable with the typeof operator, a problem occurs when you store a value with a reference type using the TypeOf operator, which returns "object" regardless of what type of object is referenced. ECMAScript introduced another Java operator, instanceof, to solve this problem. The instanceof operator is similar to the typeof operator to identify the type of object being processed. Unlike the TypeOf method, the Instanceof method requires the developer to explicitly confirm that the object is of a particular type. For example:

Listing 1. instanceof Example
12 var oStringObject = new String("hello world"); console.log(oStringObject instanceof String);   // 输出 "true"

This code asks "is the variable ostringobject an instance of a String object?" "Ostringobject is indeed an instance of a String object, so the result is" true ". Although not as flexible as the TypeOf method, the Instanceof method is useful in cases where the TypeOf method returns "Object".

General usage of the instanceof operator

Generally speaking, using instanceof is to determine whether an instance is of a certain type. For example:

Listing 2. instanceof General Usage
1234 // 判断 foo 是否是 Foo 类的实例function Foo(){} var foo = new Foo(); console.log(foo instanceof Foo)//true

In addition, the heavier point is that instanceof can be used in an inheritance relationship to determine whether an instance belongs to its parent type. For example:

Listing 3. The usage of instanceof in the relationship of inheritance
12345678 // 判断 foo 是否是 Foo 类的实例 , 并且是否是其父类型的实例function Aoo(){} function Foo(){} Foo.prototype = new Aoo();//JavaScript 原型继承var foo = new Foo(); console.log(foo instanceof Foo)//true console.log(foo instanceof Aoo)//true

The above code determines the parent class in a hierarchy of inheritance relationships, and the instanceof operator is also applicable in multi-tier inheritance relationships.

Do you really know the instanceof operator?

Looking at the above code example, is not to think that the instanceof operator is very simple, the following is a bit of complex usage.

Listing 4. instanceof Complex usage
123456789 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

Did you see the code above? Why does Object and Function instanceof themselves equal to true, while other classes instanceof themselves not equal to true? How to explain? To fundamentally understand the mysteries of instanceof, you need to start with two aspects: 1, how the operator is defined in the language specification. 2,javascript the prototype inheritance mechanism.

Detailed anatomy of the definition of the instanceof operator in ECMAScript-262 edition 3

The instanceof operator in the language specification pair is defined as follows:

Listing 5. instanceof operator definition in specification
1234567891011121314151617181920212223242526272829303132333435 11.8.6 The instanceof operator  The production RelationalExpression:      RelationalExpression instanceof ShiftExpression is evaluated as follows:  1. Evaluate RelationalExpression.  2. Call GetValue(Result(1)).// 调用 GetValue 方法得到 Result(1) 的值,设为 Result(2)  3. Evaluate ShiftExpression.  4. Call GetValue(Result(3)).// 同理,这里设为 Result(4)  5. If Result(4) is not an object, throw a TypeError exception.// 如果 Result(4) 不是 object,                                                                //抛出异常 /* 如果 Result(4) 没有 [[HasInstance]] 方法,抛出异常。规范中的所有 [[...]] 方法或者属性都是内部的,在 JavaScript 中不能直接使用。并且规范中说明,只有 Function 对象实现了 [[HasInstance]] 方法。所以这里可以简单的理解为:如果 Result(4) 不是 Function 对象,抛出异常 */  6. If Result(4) does not have a [[HasInstance]] method,    throw a TypeError exception.  // 相当于这样调用:Result(4).[[HasInstance]](Result(2))  7. Call the [[HasInstance]] method of Result(4) with parameter Result(2).  8. Return Result(7).  // 相关的 HasInstance 方法定义 15.3.5.3 [[HasInstance]] (V)  Assume F is a Function object.// 这里 F 就是上面的 Result(4),V 是 Result(2)  When the [[HasInstance]] method of F is called with value V,      the following steps are taken:  1. If V is not an object, return false.// 如果 V 不是 object,直接返回 false  2. Call the [[Get]] method of F with property name "prototype".// 用 [[Get]] 方法取                                                                 // F 的 prototype 属性 3. Let O be Result(2).//O = F.[[Get]]("prototype")  4. If O is not an object, throw a TypeError exception.  5. Let V be the value of the [[Prototype]] property of V.//V = V.[[Prototype]]  6. If V is null, return false.  // 这里是关键,如果 O 和 V 引用的是同一个对象,则返回 true;否则,到 Step 8 返回 Step 5 继续循环 7. If O and V refer to the same object or if they refer to objects    joined to each other (section 13.1.2), return true.  8. Go to step 5.

The specification definition above is obscure and looks more complex, involving many concepts, but translating this specification into JavaScript code is simple, as follows:

Listing 6. JavaScript instanceof Operator Code
1234567891011 function instance_of(L, R) {//L 表示左表达式,R 表示右表达式 var O = R.prototype;// 取 R 的显示原型 L = L.__proto__;// 取 L 的隐式原型 while (true) {    if (L === null)      return false;    if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true      return true;    L = L.__proto__;  } }
JavaScript prototype inheritance mechanism

Since this article focuses on parsing the JavaScript instanceof operator, the prototype inheritance mechanism for JavaScript is no longer explained in detail, and the following reference is from HTTP://WWW.MOLLYPAGES.ORG/MISC/JS.MP A picture that describes in detail the display of various JavaScript objects and the implicit prototype chain structure.

This article deals with the display of prototypes and implicit prototypes, so let's take a brief look at these two concepts below. In the JavaScript prototype inheritance structure, the specification uses [[Prototype]] to represent an implicit prototype of an object, which is represented in JavaScript in __proto__, and can be accessed in Firefox and Chrome, but I E can't. All JavaScript objects have the __proto__ property, but only object.prototype.__proto__ is null if this property is not modified under Firefox or Chrome. This property points to its prototype object. As for the display of the prototype, in JavaScript with the prototype attribute, this is the basic knowledge of JavaScript prototype inheritance, is not described here.

Figure 1. JavaScript prototype chain

Explaining instanceof complex usage

With the JavaScript code and prototype inheritance diagram of the instanceof operator above, it is easy to understand the instanceof operator. The following is a detailed explanation of the three examples of Object instanceof object,function instanceof Function and foo instanceof foo, which other sample readers can deduce themselves.

Listing 7. Object Instanceof Object
123456789101112 // 为了方便表述,首先区分左侧表达式和右侧表达式ObjectL = Object, ObjectR = Object; // 下面根据规范逐步推演O = ObjectR.prototype = Object.prototype L = ObjectL.__proto__ = Function.prototype // 第一次判断O != L // 循环查找 L 是否还有 __proto__ L = Function.prototype.__proto__ = Object.prototype // 第二次判断O == L // 返回 true
Listing 8. function instanceof function
12345678 // 为了方便表述,首先区分左侧表达式和右侧表达式FunctionL = Function, FunctionR = Function; // 下面根据规范逐步推演O = FunctionR.prototype = Function.prototype L = FunctionL.__proto__ = Function.prototype // 第一次判断O == L // 返回 true
Listing 9. Foo instanceof foo
12345678910111213141516 //for ease of expression, first distinguish between the left and right expressions //below according to the specifications of the progressive deduction o = Foor.prototype = Foo.prototype l = fool.__proto__ = Function.prototype //first judgment o! = L // Loop again to find if L also have __proto__ l = function.prototype.__proto__ = Object.prototype //second judgment o! = L //again loops find if L have __proto__ l = object.prototype.__proto__ = null //third judgment l = null //returns false
Brief analysis of the application of instanceof in Dojo inheritance mechanism

In JavaScript, there is no concept of multiple inheritance, just like Java. However, when declaring a class using declare in Dojo, it is allowed to inherit from more than one class. The following is an example of Dojo 1.6.1.

Listing 10. Multiple inheritance in Dojo
12345678910 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

In the above example, Foo inherits both from Aoo and Boo, but returns false when the instanceof operator is used to check if Foo is an instance of Boo. In fact, within Dojo, Foo is still only inherited from Aoo, and the methods and properties in the Boo class are copied to Foo by the mixin mechanism, so when the instanceof operator is used to check if it is an instance of Boo, it returns false. So Dojo adds a new method for each instance of the class called Isinstanceof, which is used to check for multiple inheritance.

Conclusion

This article describes in detail the instanceof operator in the JavaScript language and analyzes the algorithm of this operator in depth with the language specification. It can be a great help for readers to write complex object-oriented programs using JavaScript. All the code in this article was tested under Firefox 15.

JavaScript instanceof operator in-depth anatomy

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.