lodash源码分析之isPrototype
本文为读 lodash 源码的第一百九十五篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
gitbook也会同步仓库的更新,gitbook地址:pocket-lodash
源码分析
isPrototype
用来判断传入的值是否为一个原型对象。
new 创建实例的过程
在使用构造函数创建实例时,《Javascript 权威指南》有以下描述:
构造函数会自动创建对象,然后将构造函数作为这个对象的方法调用一次,最后返回这个新对象。
因此假设有以下的构造函数:
function Test () {
this.a = a
this.b = b
}
Test.prototype.noop = function () {}
在使用 new Test
创建实例时,可以使用 fakeNew
函数大致还原其过程:
function fakeNew () {
var obj = {}
Test.apply(obj, arguments)
obj.__proto__ = Test.prototype
return obj
}
这里的原型对象是 obj.__proto__
,也即 Test.prototype
。
任何函数都有一个 prototype
对象,这个对象里有一个属性 constructor
,constructor
属性的值指向的是原函数,在这里即是 Test
函数。
因此要判断一个对象是否为原型对象就比较简单了,只要判断这个对象是否有 constructor
属性,如果有 constructor
属性,则 constructor
的属性值应该为一个函数,并且这个函数的 prototype
属性就是这个对象。
边界条件处理
来看具体的源码:
const objectProto = Object.prototype
function isPrototype(value) {
const Ctor = value && value.constructor
const proto = (typeof Ctor === 'function' && Ctor.prototype) || objectProto
return value === proto
}
根据之前的知道,很容易就写出了以下的代码:
function isPrototype(value) {
const Ctor = value && value.constructor
const proto = typeof Ctor === 'function' && Ctor.prototype
return value === proto
}
但是,我们看到原代码中如果 Ctro
找不到protype
时,proto
还会默认成 Object.protype
。
为什么要这样做呢?
假设传入的值为 false
,现在的 isPrototype
函数得到的 proto
也为 false
,最终的结果会返回 true
,这明显不符合预期,因此这里用 Object.prototype
来做守卫。
License
署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)
最后,所有文章都会同步发送到微信公众号上,欢迎关注,欢迎提意见:
作者:对角另一面