Lodash 源码解析 —— Slice
一、Why lodash slice
首先我们先来想一个问题,JavaScript Array 不是已经有 slice 方法了吗,为什么这里还要多此一举,重新实现一遍呢?源码上面有一句注释
This method is used instead of
Array#slice
to ensure dense arrays are returned
这里说到的 dense arrays 就是有内容的数组,而不是没有内容的空数组, 先看一下原生 slice 切割数组的一个例子:
var a = new Array(3) |
上述例子中我们创建了一个长度为 3 的数组,然后用 slice 切割放到 b 里面,打印 b,返回的是 [ <3 empty items> ]
,可见这是一个有长度,但是没内容的数组,也就是 sparse arrays,直译为稀疏数组,不好听,不管还是叫英文吧。接着我们遍历了一下 b,发现 b 里面的内容并没有执行,说明 sparse array 并不会被迭代。
接着我们再来看看用 lodash slice 切割数组的一个例子:
var a = new Array(3) |
可以看到用 lodash slice 返回的是 dense array,也就是既有长度又有内容的数组,这时候我们再去遍历这个数组,可以看到已经生效了。使用 dense array 有什么好处呢?有的时候我们可能会生成一个空数组用来遍历生成一些新的空选项,这个时候使用 dense array 就比较方便了。
二、怎么保证返回的值正确?
先来看一段 demo
console.log(slice([1,2,3,4],{})); |
这段示例返回了一个空数组,咦,我明明传的是一个对象,他怎么没有报错呢?我们简化一下源码看看
function slice(array, start, end) { |
从我的注释可以可以看出为什么我们输入的 start 是 {}
,却可以返回空数组而没有报错,秘诀在于使用了 >>>
, 这个符号叫做无符号右移操作符,>>>0
作用是保证值是有意义的正整数,若无意义则缺省为 0,这里 {}>>>0
会被转换为 0,因此不会报错。
再来看一段 demo
console.log(slice([1, 2, 3, 4])); // [1, 2, 3, 4] |
这段示例我们没有给 start 值,没有报错,返回了完整的数组。这又是什么原理呢?源码中有这么一句
start = start == null ? 0 : start |
可是我们的 start 不是 undefined 吗?这里用到了二元操作符 ==
的其中一个规则,null == undefined。
参考文献:
本文标题:Lodash 源码解析 —— Slice
文章作者:Canace
发布时间:2021-05-21
最后更新:2023-05-26
原始链接:https://canace.site/lodash%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90%E2%80%94%E2%80%94array-slice/
版权声明:转载请注明出处
分享