开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情
instanceof运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上
当看到 “判断一个值是什么类型有哪些方法?”、“说一说判断原型有哪些方法?” 这样的问题的时候,也许脑海里第一个想到的是 instanceof,除此之外还有其它的几种和类型相关的判断方案:
判断原型:
- instanceof
- in
- 不管是不是在原型上,只要存在就是true
- Object.hasOwnProperty
- 判断某个属性是否在自己上面(不是原型上,如果属性在原型上会返回 false)
判断类型:
- instanceof
- typeof
- 用于判断基本类型和引用类型
- 局限性:判断null、array、object以及函数的实例(new Func())的时候,返回的都是 object
- Object.prototype.toString.call()
使用 in 和 的结合,还可以判断属性是在对象本身还是来自原型链,true:来自原型链
function hasPrototypeProperty(obj, property) {
return !obj.hasOwnProperty(property) && property in obj;
}
instanceof
instanceof可以对不同的实例对象进行判断,判断方法是根据对象的原型链依次向下查询
代码实现
思路:
- 如果判断的数据是 基本数据类型 或者 null 直接返回 false
- Object.getPrototypeOf() 获取参数的原型对象
- 循环直到 原型对象为空(未找到)或 原型对象等于 target.prototype(已找到),否则再获取原型对象继续寻找
function myInstanceof (data, target) {
if (!['function', 'object'].includes(typeof data) || data === null) return false
// if(typeof data != 'object' && typeof data != 'function' || data == null){
// return false
// }
let proto = Object.getPrototypeOf(data)
while (true) {
if (proto == null) return false // proto == null 遍历完毕,还没找到
if (proto == target.prototype) return true // 找到相同的原型对象
proto = Object.getPrototypeOf(proto) // 继续找
}
}
console.log(myInstanceof("hello", String)); // false
console.log(myInstanceof(new String("hello"), String)); // true
console.log(myInstanceof(Date, Function)); // true
console.log(myInstanceof(null, Object)); // false
console.log(myInstanceof({msg:111}, Object)); // true
运行结果:
注意
- instanceof 没法判断
null - 当判断不属于原型时,要注意
!的位置。正确写法:
if (!(orange instanceof Fruits)) {}
错误写法:当 orange 存在时,!orange 的取值会一直为 false,判断后的结果会一直为 false
if (!orange instanceof Fruits) {}
手写 instaceof
分为基本数据类型和引用数据类型判断