instanceof
定义
obj instanceof Constructor; 我们用 instanceof 来检测 Constructor.prototype 是否存在于参数 obj 的原型链上。
使用
function Person() {};
var person1 = new Person();
person1 instanceof Person; // true;
person1 instanceof Object; // true
我们可以看到 person1 同时还属于 Object 类。因为从原型上来看, Person 继承自 Object.
instanceof 算法如下:
如果 obj instanceof Class 算法如下:
- 首先先检查 Constructor 是否存在静态方法 Symbol.hasInstance, 有就直接调用。
class Person() {
[Symbol.hasInstance](obj) {
if (obj.flag) return true;
}
};
var person1 = new Person();
person1 instanceof Person; // false
- 但是对于 ES6 之前是没有 class 的,所以只能使用构造函数。并且是没有 Symbol 的。
obj instanceof Constructor 检查 Constructor.prototype 是否等于 obj 的原型链中的原型之一。
obj.__proto__ === Constructor.prototype?
obj.__proto__.__proto__ === Constructor.prototype ?
...
直到找到才会返回 true. 否则就 false。
Constructor.prototype.isPrototypeOf(obj)
用来检测 Constructor.prototype 的是否存在于参数 obj 的原型链上。
注意。
instanceof 检查的是 Constructor.prototype 与 Constructor 无关。
看一道面试题
function A() {};
function B() {};
A.prototype = B.prototype = {};
var a = new A();
a instanceof B; // true
这一道的关注点是在于 检测 B.prototype 的原型链上是否存在 对象a, a是 A的实例,也就是相当于 a instanceof A; A.prototype 和 B.prototype 是指向一块区域的。
实现 instanceof
function instanceof(constructor, obj) {
var left = obj.__proto__;
var right = constructor.prototype;
while (true) {
if (left === null) {
return false;
}
if (left === right) {
return true;
}
left = left.__proto__;
}
}
实现原理就是 obj.proto —> 一直往上找,与 constructor.prototype 相等就返回,不想等就继续找,直到 null。