跳到主要内容

instanceof

2023年06月15日
柏拉文
越努力,越幸运

一、认识


instanceof 在原型链上查找,查到即是其实例

注意
  1. isPrototypeOf()instanceof 有什么区别?

    • a.isPrototypeOf(b): 针对 a 本身进行检查

    • b instanceof b: 针对 b.prototype 进行检查

二、语法


console.log(1 instanceof Number); // false
console.log("" instanceof String);
console.log(true instanceof Boolean);
console.log({} instanceof Object); // true
console.log([] instanceof Array); // true
console.log(function () {} instanceof Function); // true

三、场景


场景一、实现一个只可以通过new的方式调用的函数

function Vue() {
if (!(this instanceof Vue)) {
console.log(
"Vue is a constructor and should be called with the `new` keyword"
);
return;
}
console.log("Vue 实例");
}

Vue();

const vue = new Vue();

四、原理 Polyfill


instanceof 通过原型链判断 A instanceof B, 在A原型链中层层查找,是否有原型等于B.prototype,如果一直找到A的原型链的顶端(null;即Object.proptotype.__proto__),仍然不等于B.prototype,那么返回false,否则返回true

递归版:

function myInstanceof(obj, constructor) {
if (!(obj && ["object", "function"].includes(typeof obj))) {
return false;
}
let proto = Object.getPrototypeOf(obj);
if (proto === constructor.prototype) {
return true;
} else if (proto === null) {
return false;
} else {
return myInstanceof(proto, targetConstructor);
}
}

function Foo() {}
const foo = new Foo();
console.log(myInstanceof(foo, Foo));

迭代版:

function myInstanceof(obj, constructor) {
if (!(obj && ["object", "function"].includes(typeof obj))) {
return false;
}
let proto = obj;
while ((proto = Object.getPrototypeOf(obj))) {
if (proto === constructor.prototype) {
return true;
} else if (proto === null) {
return false;
}
}
return false;
}

function Foo() {}
const foo = new Foo();
console.log(myInstanceof(foo, Foo));