First, Breif
As we all know, instanceof is generally used to check whether a object is an instance of Class B or subclass. The problem is that there is no concept of class inheritance in JS (although there are constructors), so how does instanceof judge that a object is an instance of a B constructor? This article will be analyzed and recorded for future reference.
Second, Reference 2 ecma-262-3 Spec
http://bclary.com/2004/11/07/#a -11.8.6
The production relationalexpression:relationalexpression instanceof shiftexpression is Evaluated as follows:
1. Evaluate relationalexpression.
2.Call GetValue (Result (1)).
3.Evaluate shiftexpression.
4.Call GetValue (Result (3)).
5.If Result (4) is not a object, throw a TypeError exception.
6.If Result (4) does not has a [[Hasinstance]] method, throw a TypeError exception.
7.Call the [[Hasinstance]] method of result (4) with parameter result (2).
8.Return Result (7).
From the above definition we can draw the following content:
1. The actual value of the Shiftexpression (GetValue (Evaluate (shiftexpression)) must be [object Function], or the typeerror exception is thrown;
2. Instanceof's actual judgment is to call relationalexpression 's internal Method [[Hasinstance]] to handle it.
Let's take a closer look at [[hasinstance]] Definition
http://bclary.com/2004/11/07/#a -15.3.5.3
Assume F is a Function object.
When the [[Hasinstance]] method of an F is called with value V, the following steps is taken:
1. If V is not a object, return false.
2. Call the [[Get]] method of F with property name "Prototype".
3. Let O is Result (2).
4. If O is not a object, throw a TypeError exception.
5. Let V is the value of the [[Prototype]] property of v.
6. If V is null, return false.
7. If O and V refer to the same object or If they refer to objects joined to all other (13.1.2), return true.
8. Go to step 5.
The definition above is not very clear, we translate it into JS implementation of it
///Ie5.5~9, this method is invalid because the object's internal property [[Prototype]] cannot be accessed through __proto__
;(function (rnotobj) {function.prototype['[[hasinstance]]'] =function (value) {//1. If V is not a object, return False if(Rnotobj.test (typeofValue))return false //2. Call the [[Get]] method of F with property name "prototype"//4. If O is not an object, throw a TypeError exception varO = This. Prototypeif(Rnotobj.test (typeofO))ThrowTypeError ()//5. Let V is the value of the [[Prototype]] Prototype of v//6. If V is null, return False if(NULL= = = (value = value.__proto__))return false //7. If O and V refer to the same object//8. Go to step 5 returnO = = = Value | | This['[[hasinstance]]'] (value)}} (/$[^of]//*Not begin with O (bject) neither F (unction)*/))
Now a little summary, the instanceof B bottom of the operational mechanism key points are as follows:
1. The data type of B must be [object Function], otherwise it will be thrown typeerror;
2. If a is primitive value returns false directly, if the data type of a is an object then perform subsequent operations;
3. Returns true if and only if B.prototype is in the prototype chain of a(because object.prototype.__proto__ is null, so prototype Chain is a finite chain list);
Perhaps people will be function.prototype['[[[Hasinstance]]' Implementation of why the success of the question, we first look at the film
You can know that all functions are __proto__ by default to Function.prototype , and function.__proto__ Function.prototype points to the same object.
Both points in Chrome point to function Empty () {} , so attributes added to Function.protoype also appear in the function's prototype chain.
Iv. If they refer to objects joined
Objects joined is actually the bottom-up optimization method adopted by spec-makers (such as V8, SpiderMonkey).
function A () { function B () {} return B}var c = A ()var D = A ()// if JavaScript engine implements the objects Joined, then object, thereby reducing consumption from space and time.
Wu, conclusion
Before reading a lot of instanceof article but always understand it is not thorough, it seems to see spec comparison.
Respect the original, reprint please indicate from: http://www.cnblogs.com/fsjohnhuang/p/4231454.html Fat boy John ^_^
Liu, Thanks
Http://www.w3cfuns.com/article-5597466-1-1.html
http://dmitrysoshnikov.com/ecmascript/chapter-5-functions/
JS Magic Hall: Re-recognize instanceof