资讯专栏INFORMATION COLUMN

Lodash学习笔记 - slice函数

lei___ / 1338人阅读

摘要:文档地址中文文档英文文档源码地址第一个函数是,不过源码中依赖了,所以第一篇文章就从开始。这个函数的作用就是裁剪数组,从下标开始,到下标结束,但是并不包含,并将结果作为一个数组返回。并且注明了这个方法用于代替来确保数组正确返回。

百忙之中(闲来无事)想抽点时间好好读一下源码,于是就选了Lodash来写一个系列罢。读源码顺序就按照loadsh文档顺序来。

文档地址:中文文档   英文文档
源码地址:gayhub

第一个函数是chunk,不过源码中chunk依赖了slice,所以第一篇文章就从slice开始。

    _.slice(array, [start=0], [end=array.length])

这个函数的作用就是裁剪数组array,从start下标开始,到end下标结束,但是并不包含end,并将结果作为一个数组返回。并且注明了:

Note: 这个方法用于代替 Array#slice 来确保数组正确返回。

看起来和原生javascript的slice没有区别,那为什么要重写这个函数呢?有以下几个原因:

比原生slice更快,测试地址,结果如图:

有更好的兼容性,IE < 9 时无法转化伪数组对象(例如DOM),出处

下面我们来看一下具体的实现,一行行来看代码:

首先是数组array是否合法的判断:

let length = array == null ? 0 : array.length
if (!length) {
    return []
}

开始位置start和结束位置end默认值:

start = start == null ? 0 : start
end = end === undefined ? length : end

支持负数start,以及start合法性检测:超出数组长度即为0,否则从右往左数

if (start < 0) {
    start = -start > length ? 0 : (length + start)
}

end合法性检测:超出数组长度即为数组长度
如果end为负数,则从右往左数

end = end > length ? length : end
if (end < 0) {
    end += length
}

数组裁剪后的长度,这里为了速度所以使用了>>>来向下取整
start向下取整

length = start > end ? 0 : ((end - start) >>> 0)
start >>>= 0

通过循环来浅拷贝数组的元素,最终返回

let index = -1
const result = new Array(length)
while (++index < length) {
    result[index] = array[index + start]
}
return result

最后贴个源码:

/**
 * Creates a slice of `array` from `start` up to, but not including, `end`.
 *
 * **Note:** This method is used instead of
 * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
 * returned.
 *
 * @since 3.0.0
 * @category Array
 * @param {Array} array The array to slice.
 * @param {number} [start=0] The start position. A negative index will be treated as an offset from the end. 
 * @param {number} [end=array.length] The end position. A negative index will be treated as an offset from the end. 
 * @returns {Array} Returns the slice of `array`.
 */
function slice(array, start, end) {
  let length = array == null ? 0 : array.length
  if (!length) {
    return []
  }
  start = start == null ? 0 : start
  end = end === undefined ? length : end

  if (start < 0) {
    start = -start > length ? 0 : (length + start)
  }
  end = end > length ? length : end
  if (end < 0) {
    end += length
  }
  length = start > end ? 0 : ((end - start) >>> 0)
  start >>>= 0

  let index = -1
  const result = new Array(length)
  while (++index < length) {
    result[index] = array[index + start]
  }
  return result
}

export default slice

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93409.html

相关文章

  • Lodash学习笔记 - chunk函数

    摘要:文档地址中文文档英文文档源码地址将数组拆分成多个长度的区块,并将这些区块组成一个新数组。如果无法被分割成全部等长的区块,那么最后剩余的元素将组成一个区块。 百忙之中(闲来无事)想抽点时间好好读一下源码,于是就选了Lodash来写一个系列罢。读源码顺序就按照loadsh文档顺序来。 文档地址:中文文档   英文文档源码地址:gayhub _.chunk(array, [size...

    DrizzleX 评论0 收藏0
  • 学习笔记: JS数组

    摘要:数组元素甚至可以是对象或其它数组。它执行的是浅拷贝,这意味着如果数组元素是对象,两个数组都指向相同的对象,对新数组中的对象修改,会在旧的数组的相同对象中反应出来。 JS中的数组是弱类型的,数组中可以含有不同类型的元素。数组元素甚至可以是对象或其它数组。JS引擎一般会优化数组,按索引访问数组常常比访问一般对象属性明显迅速。数组长度范围 from 0 to 4,294,967,295(2^...

    archieyang 评论0 收藏0
  • JavaScript 数组分组的实现

    摘要:今天回答了的问题生产嵌套数组也就是对数组分组更好的写法。实现像这种,目标数组长度和原数组长度不一致的情况,函数式写法很容易想到函数。小结数组分组是一个很简单的问题,有很多种方法来处理。 今天回答了 @_bleach 的问题:JS生产嵌套数组(也就是对数组分组)更好的写法。回答的过程中对 lodash _.chunk() 产生了好奇,所以分析了一下它的源码,再加上我自己的解决方案,收集...

    Coly 评论0 收藏0
  • Lodash源码讲解-chunk函数

    摘要:原文首发于源码讲解这是我们阅读源码的第篇博客,在这篇文章里我们来学习一下的方法。好啦,关于函数暂时就先讲到这里啦。与恶龙缠斗过久自身亦成为恶龙凝视深渊过久深渊将回以凝视。 原文首发于Lodash源码讲解 这是我们阅读Lodash源码的第2篇博客,在这篇文章里我们来学习一下Lodash的chunk方法。 chunk函数内部依赖其他的函数,依赖的函数如下所示; slice 按照惯例,我们先...

    ISherry 评论0 收藏0
  • 《你不知道的javascript》笔记_对象&原型

    摘要:上一篇你不知道的笔记写在前面这是年第一篇博客,回顾去年年初列的学习清单,发现仅有部分完成了。当然,这并不影响年是向上的一年在新的城市稳定连续坚持健身三个月早睡早起游戏时间大大缩减,学会生活。 上一篇:《你不知道的javascript》笔记_this 写在前面 这是2019年第一篇博客,回顾去年年初列的学习清单,发现仅有部分完成了。当然,这并不影响2018年是向上的一年:在新的城市稳定、...

    seasonley 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<