作用
用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上。
instanceof缺点
- 不考虑当前实例对象是否是该构造函数的实例对象,只要能在当前实例对象的原型链上找到该结构函数的原型对象,就会返回
true。 - 实例对象的原型链被改写时,使用
instanceof判断对象是否是构造函数的实例对象时也会返回true
看以下代码:
function Person(name, age) {
this.name = name;
this.age = age;
}
const person = new Person('cc', 21);
console.log(person instanceof Person); // true
此时person.__proto__ === Person.prototype,打印结果为true。
const obj = {};
obj.__proto__ = Person.prototype;
console.log(obj instanceof Person); // true
此时obj的__proto__被设置为构造函数Person的原型对象,即原型链被改写,打印结果为true。
手写instanceof
function _instanceof(left, right) {
if (!left || !right) return;
if (typeof left !== 'object') {
throw Error('参数1非对象');
}
if (typeof right !== 'function') {
throw Error('参数2非构造函数');
}
// 获取左侧对象的原型
const proto = Object.getPrototypeOf(left);
// 循环获取右侧原型,找到了就终止循环
while(proto !== right.prototype) {
// 找不到原型返回false
if (proto === null) return false;
// 沿原型链获取原型
proto = Object.getPrototypeOf(proto);
}
return true;
}
Object.getPrototypeOf是 Object 提供的获取对象原型的方法;
object.__proto__,是手动去访问对象的原型。
两者作用相同,即Object.getPrototypeOf(proto) = proto.__proto__。因此,可以使用以下写法:
function _instanceof(left, right) {
// 边界值判断
// 替换为object.__proto__
const proto = left.__proto__;
while(proto !== right.prototype) {
if (proto === null) return false;
proto = proto.__proto__;
}
return true;
}