You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
arrayLikeKeys 的作用是将 value 的 key 收集在一个数组中,作为结果返回。如果是 array、arguments、buffer、typedArray 等类数组类型,则还会收集索引。
源码如下:
consthasOwnProperty=Object.prototype.hasOwnPropertyfunctionarrayLikeKeys(value,inherited){constisArr=Array.isArray(value)constisArg=!isArr&&isArguments(value)constisBuff=!isArr&&!isArg&&isBuffer(value)constisType=!isArr&&!isArg&&!isBuff&&isTypedArray(value)constskipIndexes=isArr||isArg||isBuff||isTypeconstlength=value.lengthconstresult=newArray(skipIndexes ? length : 0)letindex=skipIndexes ? -1 : lengthwhile(++index<length){result[index]=`${index}`}for(constkeyinvalue){if((inherited||hasOwnProperty.call(value,key))&&!(skipIndexes&&(// Safari 9 has enumerable `arguments.length` in strict mode.(key==='length'||// Skip index properties.isIndex(key,length))))){result.push(key)}}returnresult}
收集索引
skipIndexes 用来标识传入的 value 是否为 array、arguments、buffer、typedArray 等类数组类型,如果是,则还需要收集索引。
首先获取 value 的长度,如果 skipIndexes 标识为 true,则初始化一个长度为 length 的数组,用来保存索引。
while(++index<length){result[index]=`${index}`}
如果 skipIndexes 为 true,索引 index 的初始值为 -1,否则为 length,不会进入这个循环,因为使用 ++index,因此,存入 result 的第一个值为 0。
可以看到,后面会用 for...in 收集 key,其实索引也会在 for...in 中遍历出来,那为什么还要多此一举,用 while 循环来遍历索引呢?
因为像数组会有稀疏数组这种情况,在 for...in 中,索引不会全部遍历出来。
收集属性
传入的 value 可能不是以上类型,或者以上的类型还有其他属性,这些属性也是要收集的。
源码如下:
for(constkeyinvalue){if((inherited||hasOwnProperty.call(value,key))&&!(skipIndexes&&(// Safari 9 has enumerable `arguments.length` in strict mode.(key==='length'||// Skip index properties.isIndex(key,length))))){result.push(key)}}
使用 for...in 来遍历,for...in会遍历原型链上的属性,默认只收集 value 本身的属性,即属性要通过 Object.prototype.hasOwnProperty 的检测,但是可以通过传入标志位 inherited 来收集原型链上的属性。
本文为读 lodash 源码的第一百二十九篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
gitbook也会同步仓库的更新,gitbook地址:pocket-lodash
依赖
《lodash源码分析之isArguments》
《lodash源码分析之isBuffer》
《lodash源码分析之isIndex》
《lodash源码分析之isTypedArray》
源码分析
arrayLikeKeys
的作用是将value
的key
收集在一个数组中,作为结果返回。如果是array
、arguments
、buffer
、typedArray
等类数组类型,则还会收集索引。源码如下:
收集索引
skipIndexes
用来标识传入的value
是否为array
、arguments
、buffer
、typedArray
等类数组类型,如果是,则还需要收集索引。首先获取
value
的长度,如果skipIndexes
标识为true
,则初始化一个长度为length
的数组,用来保存索引。如果
skipIndexes
为true
,索引index
的初始值为-1
,否则为length
,不会进入这个循环,因为使用++index
,因此,存入result
的第一个值为0
。可以看到,后面会用
for...in
收集key
,其实索引也会在for...in
中遍历出来,那为什么还要多此一举,用while
循环来遍历索引呢?因为像数组会有稀疏数组这种情况,在
for...in
中,索引不会全部遍历出来。收集属性
传入的
value
可能不是以上类型,或者以上的类型还有其他属性,这些属性也是要收集的。源码如下:
使用
for...in
来遍历,for...in
会遍历原型链上的属性,默认只收集value
本身的属性,即属性要通过Object.prototype.hasOwnProperty
的检测,但是可以通过传入标志位inherited
来收集原型链上的属性。因此收集的属性要满足
(inherited || hasOwnProperty.call(value, key))
这个条件。因为类数组的索引已经收集过,因此在
for...in
遍历时需要将索引排除。条件如下:
本来
arguments
的length
属性是不枚举,但是在 Safari 9 中,在strict mode
下,length
是可以枚举的,因此也要排除。最终条件如下:
符合条件的数组也存入
result
中。License
署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)
最后,所有文章都会同步发送到微信公众号上,欢迎关注,欢迎提意见:
作者:对角另一面
The text was updated successfully, but these errors were encountered: