instanceof描述
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。简单来说就是一个实列对象是否在某个构造函数的原型上面。
代码演示
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);
console.log(auto instanceof Car);
// expected output: true
console.log(auto instanceof Object);
// expected output: true
第一版instanceof
function myInstanceof1(L, R) {
// 声明一个变量获取对象的__proto__
let link = L.__proto__
// 做循环(当link最终指向null,如果指向null的情况下都找不到那就返回false)
while (link !== null) {
// 如果找到说明R.prototype在L的原型链上,即返回true
if(link === R.prototype) return true
// 逐级向下
link = link.__proto__
}
return false
}
// 测试
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);
console.log(myInstanceof1(auto, Car)); // true
console.log(myInstanceof1(auto, Object)); // true
console.log(auto instanceof Car); // true
console.log(auto instanceof Object); // true
主要功能实现接下来对一些特殊情况进行判断。
先看看instanceof如何处理左右两侧的参数问题
1 instanceof Number // false
'' instanceof String // false
true instanceof Boolean // false
null instanceof Boolean // false
NaN instanceof Number // false
undefined instanceof Number // false
0 instanceof Number // false
可以看到对于左侧参数无论你输入什么类型的参数instanceof都是正常执行。来试试右侧
var a = {}
a instanceof 1 // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof '' // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof true // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof null // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof NaN // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof undefined // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof 0 // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof {} // Uncaught TypeError: Right-hand side of 'instanceof' is not callable
从上来的判断可知
- 当左边不是一个对象的时候直接返回false。
- 当右边不是一个函数或者没有原型的时候直接报错。
最终版本
function myInstanceof(L = null, R) {
// 对于左侧参数如果是非对象直接返回false
if (Object(L) !== L) return false
// 对于右侧参数可以认为只能为函数且不能没有Prototype属性
if (typeof R !== 'function' || !R.prototype) throw new TypeError('Right-hand side of 'instanceof' is not an object')
// 声明一个变量获取对象的__proto__
let link = L.__proto__
// 做循环(当link最终指向null,如果指向null的情况下都找不到那就返回false)
while (link !== null) {
// 如果找到说明R.prototype在L的原型链上,即返回true
if(link === R.prototype) return true
// 逐级向下
link = link.__proto__
}
return false
}