grammar
object instanceof constructor
parameter
object:
The object to be detected.
constructor:
A constructor
describe:
The instanceof operator is used to detect whether the constructor.prototype exists on the prototype chain of the parameter object.
// Define the constructor function C(){} function D(){} var o = new C();// true, because Object.getPrototypeOf(o) === C.prototypeo instanceof C; // false, because D.prototype is not on the prototype chain of o instanceof D; o instanceof Object; // true, because Object.prototype.isPrototypeOf(o) returns trueC.prototype instanceof Object // true, same as above C.prototype = {};var o2 = new C();o2 instanceof C; // trueo instanceof C; // false,C.prototype points to an empty object, which is not on the prototype chain of o.D.prototype = new C(); // Inherit var o3 = new D();o3 instanceof D; // trueo3 instanceof C; // trueIt should be noted that if the expression obj instanceof Foo returns true, it does not mean that the expression will return ture forever, because the value of the Foo.prototype property may change, and the changed value may not exist on the obj prototype chain, and the value of the original expression will become false. In another case, the value of the original expression will also change, which is the case where the prototype chain of the object obj is changed. Although in the current ES specification, we can only read the prototype of the object and cannot change it, it can be achieved with the help of the non-standard __proto__ magic attribute. For example, after executing obj.__proto__ = {}, obj instanceof Foo will return false.
instanceof and multi-global objects (interaction between multiple frames or multiple windows)
In a browser, our scripts may need to interact between multiple windows. Multiple windows mean multiple global environments, and different global environments have different global objects, thus having different built-in type constructors. This may cause some problems. For example, the expression [] instanceof window.frames[0].Array will return false because Array.prototype !== window.frames[0].Array.prototype, so you must use Array.isArray(myObj) or Object.prototype.toString.call(myObj) === "[object Array]" to determine whether myObj is an array.
Example
The general usage of instanceof is to determine whether a is of type b:
console.log(true instanceof Boolean); // false console.log(new Number(1) instanceof Number); // true
instanceof can also determine the parent type:
function Father() {}function Child() {}Child.prototype = new Father();var a = new Child();console.log(a instanceof Child); // trueconsole.log(a instanceof Father); // trueThe Child constructor inherits from Father. Instance a is undoubtedly constructed by Child, but why is it also an instance of Father? In fact, the kernel of the instanceof operator can be simply described with the following code:
function check(a, b) { while(a.__proto__) { if(a.__proto__ === b.prototype) return true; a = a.__proto__; } return false;}function Foo() {}console.log(Object instanceof Object === check(Object, Object)); // true console.log(Function instanceof Function === check(Function, Function)); // true console.log(Number instanceof Number === check(Number, Number)); // true console.log(String instanceof String === check(String, String)); // true console.log(Function instanceof Object === check(Function, Object)); // true console.log(Foo instanceof Function === check(Foo, Function)); // true console.log(Foo instanceof Foo === check(Foo, Foo)); // true console.log(Foo instanceof Foo === check(Foo, Foo)); // true console.log(Foo instanceof Foo === check(Foo, Foo)); // trueSimply put, if a is an instance of b, then a can definitely use the methods and properties defined in b's prototype. Then, in code, it means that there are objects with the same value in a prototype chain with b.prototype, so just follow a prototype chain of a to search layer by layer.
It is also worth noting that String Number Boolean and Function are functions, and functions are uniformly constructed from Function. They are like any simple function, and they can use the prototype properties on the Function:
Function.prototype.a = 10;console.log(String.a); // 10
Finally, let’s briefly talk about the first two questions.
// For the sake of convenience of expression, first distinguish the left expression and the right expression FunctionL = Function, FunctionR = Function; // Below is gradually deduced according to the specifications O = FunctionR.prototype = Function.prototype L = FunctionL.__proto__ = Function.prototype // First judgement O == L // Return true// For the sake of convenience of expression, first distinguish the left expression and the right expression StringL = String, StringR = String; // Below is gradually deduced according to the specifications O = StringR.prototype = String.prototype L = StringL.__proto__ = Function.prototype // The first time judges O != L // Loops again to find whether L still has __proto__ L = String.prototype.__proto__ = Object.prototype // The second time judges O != L // Loops again to find whether L still has __proto__ L = String.prototype.__proto__ = null // The third time judges L == null // Return false