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 算法如下:

  1. 首先先检查 Constructor 是否存在静态方法 Symbol.hasInstance, 有就直接调用。
class Person() {
    [Symbol.hasInstance](obj) {
        if (obj.flag) return true;
    }
};
var person1 = new Person();
person1 instanceof Person;  //  false
  1. 但是对于 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。