2020年3月13日
《每日一题系列 》
作者:王二狗
原文链接:实现 instanceof 并说明其工作原理
博客:掘金、思否、知乎、简书、CSDN
点赞再看,养成习惯,每日一题系列会一直更新下去,你们的支持是我持续分享的最大动力
实现 instanceof
//Obj 被检测对象 Constructor 构造函数
function instance_of(Obj, Constructor){
let implicitPrototype = Obj.__proto__;// 隐式原型
let displayPrototype = Constructor.prototype;// 显式原型
while(true){
if(implicitPrototype === null){
return false
}else if(implicitPrototype === displayPrototype){
return true
}
implicitPrototype = implicitPrototype.__proto__
}
}
console.log(instance_of([], Array)) // true
console.log(instance_of([], String)) // false
工作原理
instanceof
的工作原理就是测试构造函数的prototype
是否出现在被检测对象obj
的原型链上。
[] instanceof Array // true
({}) instanceof Object // true
(()=>{}) instanceof Function // true
注意:instanceof 也不是万能的。
举个例子:
let arr = []
let obj = {}
arr instanceof Array // true
arr instanceof Object // true
obj instanceof Object // true
obj instanceof Array // false
在这个例子中,arr
数组相当于 new Array()
出的一个实例,所以 arr.__proto__ === Array.prototype
,又因为 Array
属于 Object
子类型,即 Array.prototype.__proto__ === Object.prototype
,因此 Object
构造函数在 arr
的原型链上。所以 instanceof
仍然无法优雅的判断一个值到底属于数组还是普通对象。
Object.prototype.toString()
可以说Object.prototype.toString()
是判定 JS
数据类型的最佳解决方案,具体用法请看以下代码:
Object.prototype.toString.call({})
// '[object Object]'
Object.prototype.toString.call([])
// '[object Array]'
Object.prototype.toString.call(() => {})
// '[object Function]'
Object.prototype.toString.call('wangergou')
// '[object String]'
Object.prototype.toString.call(null)
// '[object Null]'
Object.prototype.toString.call(undefined)
// '[object Undefined]'
从上面的代码可以看到,我们传入任何的值都能准确的返回其对应的对象类型。
但是其中需要注意点还是需要说一下的:
- 该方法本质就是依托
Object.prototype.toString()
方法得到对象内部属性[[Class]]
- 传入原始类型却能够判定出结果是因为对值进行了包装
null
和undefined
能够输出结果是内部实现有做处理
为了更加方便的使用Object.prototype.toString()
,我们可以对其进行一个简单的封装:
var type = function(data) {
var toString = Object.prototype.toString;
var dataType = toString
.call(data)
.replace(/[objects(.+)]/, "$1")
.toLowerCase()
return dataType
};
type({})
// '[object Object]'
type([])
// '[object Array]'
type(() => {})
// '[object Function]'
type('wangergou')
// '[object String]'
type(null)
// '[object Null]'
type(undefined)
// '[object Undefined]'
告诫自己,即使再累也不要忘记学习,成功没有捷径可走,只有一步接着一步走下去。 共勉!
文章中如有不对的地方,欢迎小伙伴们多多指正。
谢谢大家~