在学习过程中遇到一个要求手写 instanceof 的题目,论使用的话,用于检测数据类型还是比较方便的,但如果要求写出功能代码,我却懵逼了。花了一些功夫才一知半解,决定将知识点总结下来。
instanceof的作用
- instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
- 通常用于检测数据类型
对原型链的理解
每个对象都可以有一个原型__proto__,这个原型还可以有它自己的原型,以此类推,形成一个原型链。查找特定属性的时候,我们先去这个对象里去找,如果没有的话就去它的原型对象里面去,如果还是没有的话再去向原型对象的原型对象里去寻找。
原型链上的所有原型都是对象,所有的对象最终都是由Object构造的。
由于Object是构造函数,Object.prototype的下一级是Object.prototype.__proto__。原型链终点是Object.prototype.__proto__,而Object.prototype.__proto__=== null // true,所以,原型链的终点是null。
手写具有 instanceof 功能的函数
要求以Boolean的形式返回第一个实例参数是否在第二个函数参数的原型链上。
//javascript
//个人能力问题,只是简单实现了一下
const _instanceof = (target, Fn) => {
// 对基本类型进行判断
if (target === null || typeof target !== 'object') {
return false
}
// 根据原型链的理解,循环去找原型的原型
while (target) {
if (target === Fn.prototype)
return true
target = target.__proto__
//直到原型链终点null
}
return false
}
测试结果
测试组:
console.log(_instanceof([1, 2, 3], Array)); //true
console.log(_instanceof(123, Object)); // false
console.log(_instanceof(123, Number)); // false
遇到的问题:
第三组测试的结果返回false,这触及到了我的知识盲区,于是我测试了 123 instanceof Number ,结果依然是false。why?(没有这个疑问的请忽略)
因为 instanceof 这个运算符是用来测试一个对象的原型链上是否有该原型的构造函数,而123是Number类型,并不是一个对象。而如果我们使用Number构造一个实例化对象,即new Number(123) instanceof Number ,这时则返回true。
再测试_instanceof(new Number(123), Number),则能够成功返回true。
console.log(123 instanceof Number); //false
console.log(new Number(123) instanceof Number); //true
console.log(_instanceof(123, Number)); //true
以上为个人查阅资料总结,如有错误或不足,欢迎指出。