js Array.slice的8种不同用法示例


Posted in Javascript onJuly 10, 2019

前言

JS数组slice方法是JS语言中最强大、最常用的内建函数之一。

随着React和其他面向功能的JavaScript实践的兴起,它变得越来越重要,原因有两个:

  • 函数式编程,尤其是高阶函数,与数据列表密切配合
  • 函数式编程需要纯函数,即不会产生副作用或修改输入数据的函数

JavaScript 数组slice方法符合这两个标准。

slice方法可以在不修改原始列表的情况下创建列表子集的浅拷贝。因此,它为编写函数式 JS 提供了一个关键的构建块。

在这篇文章中,我们将通过实例来掌握slice方法,探索它的8种不同用法。

注意:slice 方法不要与splice方法混淆,splice方法会修改原始数组。

slice 工作原理

在深入研究一些更高级的用法之前,让我们看一下slice方法的基础知识。

如MDN文档,slice 是数组上的一个方法,它最多有两个参数:

arr.slice([begin[, end]])

begin

从该索引处开始提取原数组中的元素,如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2)表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。
如果省略 begin,则 slice 从索引 0 开始。

end

在该索引处结束提取原数组元素(从0开始)。slice会提取原数组中索引从 begin 到 end 的所有元素(包含begin,但不包含end)。

slice(1,4) 提取原数组中的第二个元素开始直到第四个元素的所有元素 (索引为 1, 2, 3的元素)。

如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取。 slice(-2,-1)表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。

如果 end 被省略,则slice 会一直提取到原数组末尾。如果 end 大于数组长度,slice 也会一直提取到原数组末尾。

基本用法

我们的前4个例子突出slice的核心功能。

用法1:简单的复制

const arr2 = arr.slice

没有任何参数的slice执行一个简单的浅拷贝。当前,主流的用法还是使用展开运算符合来实现,但是如果在旧的代码库中,或者没有使用babel的构建步骤,可能仍然希望使用slice。

用法2:获取从 N 开始的子数组

使用slice方法最简单的方法就是原始数组从N开始抽取的所有元素。

一种情况是希望弹出数组的第一个元素并使用它,返回剩余的数组,但希望在不修改原始数组的情况下执行此操作。

function useone (arr) {
 const usedItem = arr[0]
 return arr.slice(1)
}

用法3:获取从末尾 N 开始的子数组

slice的另一种使用方法是获取数组的末尾,利用的是负索引从末尾开始计数。

这种负索引使删除任意数量的元素变得超级简单。例如,如果你只想抓取3个

const last3 = arr.slice(-3)

用法4:获取数组的前n个

获取数组的前面的数,我们需要使用第二个参数:end。

当有两个参数时,slice方法返回一个从begin开始但不包括end的集合。

由于JavaScript数组是从0开始的(索引从0开始),这使得获取前N个元素变得非常简单:

const first4 = arr.slice(0, 4)

用法5:获取数组中某段子数组

如果我们想要使用slice从任何索引开始获取数组的一段,该怎么办?

为此,我们需要从 (begin, length) 转换为(begin, end)。 计算逻辑很简单,我们可以定义一个简单的函数来做到这一点:

function pullSegment(arr, begin, length) {
 return arr.slice(begin, begin + length);
}

处理类似数组的对象

JavaScript中,数组是一个特殊的对象,其property名为正整数,且其length属性会随着数组成员的增减而发生变化,同时又从Array构造函数中继承了一些用于进行数组操作的方法。

而对于一个普通的对象来说,如果它的所有property名均为正整数,同时也有相应的length属性,那么虽然该对象并不是由Array构造函数所创建的,它依然呈现出数组的行为,在这种情况下,这些对象被称为 “类数组对象” 。

slice方法也可用于类似数组的对象。

一些类似数组包如arguments(用于访问传递给函数的所有参数的关键字),NodeLists(从返回节点列表的任何DOM API方法返回),甚至是使用数字索引并添加length属性的原始对象。

要在类似数组的对象上使用slice方法,需要直接从Array.prototype引用它,如下所示:

Array.prototype.slice.call(arguments)

在这特定的场合中会很有用处。

用法6:将类似数组的对象转换为数组

slice在类似数组的对象上的一个常见用途是将它们转换为实际数组。 例如:

const args = Array.prototype.slice.call(arguments);

你为什么要这么做?为了使用数组方法。例如,想象一个像这样的函数

function addOne() { 
 return arguments.map(i => i+1); 
}

这看起来可行,但如果你试着去做,你就会得到错误:

> addOne(1, 2, 3)
TypeError: arguments.map is not a function
    at test (repl:2:18)
    at repl:1:1
    at ContextifyScript.Script.runInThisContext (vm.js:44:33)
    at REPLServer.defaultEval (repl.js:239:29)
    at bound (domain.js:301:14)
    at REPLServer.runBound [as eval] (domain.js:314:12)
    at REPLServer.onLine (repl.js:440:10)
    at emitOne (events.js:120:20)
    at REPLServer.emit (events.js:210:7)
    at REPLServer.Interface._onLine (readline.js:279:10)

这是因为arguments 实际上不是数组,而是类似数组的对象。 可以使用slice实现此功能,如下所示:

function addOne() {
 return Array.prototype.slice.call(arguments).map(i => i+1)
}

现在就可以得到了你所希望的数据:

> addOne(1, 2, 3) 
 [ 2, 3, 4 ]

用法7:将任意长度多余的参数强制转换为数组

有时希望接受函数的多余参数,组成一个数组。

较新版本的JavaScript引入了所谓的Rest语法来处理这个问题,但是如果为为了兼容旧浏览器,你可以使用slice做到这一点:

function myFunc(a, b) { 
 const extraArgs = Array.prototype.slice.call(arguments, 2); 
}

这允许使用任意数量的参数调用myFunc, 例如:

myFunc(1, 2, 3, 4, 5, 6, 7, 8)

在函数里面会得到a == 1,b === 2,extraArgs=== [3,4,5,6,7,8]

用法8:修改数组中的特定索引

slice在函数上下文中一个强大而常见的用法是替换数组中特定项的值。

从本质上讲,这很简单,只需要分配新值,但是在函数世界中,不能修改原始数组。

相反,可以将slice与扩展运算符一起使用,以返回一个相同但对于要更新的​​索引的新数组:

function replaceIdx(arr, index, newVal) {
 return [
 ...arr.slice(0, index),
 newVal,
 ...arr.slice(index + 1)
 ]
}

偏函数应用

偏函数应用,英文是partial application,也可以译作“局部应用”、“部分应用”、“偏应用”

函数式编程中的另一种常见模式是所谓的偏函数应用:将函数预先应用于函数,然后返回一个新函数。

这种模式允许你组合函数,通过使用具有不同预应用参数的相同核心函数来创建更大的可重用性。

虽然像Haskell这样的纯函数语言本身支持偏函数应用程序,但是在JavaScript中,我们可以使用slice实现一个函数来实现它

var partial = function() {
 const fn = arguments[0];
 const args = Array.prototype.slice.call(arguments, 1);

 // Return a function that calls fn
 return function() {
 var remainingArgs = Array.prototype.slice.call(arguments);
 return fn.apply(this, args.concat(remainingArgs));
 }
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
Firebug 字幕文件JSON地址获取代码
Oct 28 Javascript
javascript高级学习笔记整理
Aug 14 Javascript
jquery js 获取时间差、时间格式具体代码
Jun 05 Javascript
浅析js中取绝对值的2种方法
Jul 09 Javascript
js获取GridView中行数据的两种方法 分享
Jul 13 Javascript
jquery.mobile 共同布局遇到的问题小结
Feb 10 Javascript
AngularJS基础知识笔记之表格
May 10 Javascript
JavaScript中反正弦函数Math.asin()的使用简介
Jun 14 Javascript
zTree异步加载展开第一级节点的实现方法
Sep 05 Javascript
JS+HTML+CSS实现轮播效果
Nov 28 Javascript
vue实现随机验证码功能的实例代码
Apr 30 Javascript
JS实现网页时钟特效
Mar 25 Javascript
vue-router二级导航切换路由及高亮显示的实现方法
Jul 10 #Javascript
Vue编程式跳转的实例代码详解
Jul 10 #Javascript
微信小程序在ios下Echarts图表不能滑动的问题解决
Jul 10 #Javascript
Vue事件修饰符native、self示例详解
Jul 09 #Javascript
如何自定义微信小程序tabbar上边框的颜色
Jul 09 #Javascript
微信小程序wx.request拦截器使用详解
Jul 09 #Javascript
javascript实现图片轮播代码
Jul 09 #Javascript
You might like
PHP file_get_contents 函数超时的几种解决方法
2009/07/30 PHP
php 购物车完整实现代码
2014/06/05 PHP
PHP使用Mysql事务实例解析
2014/09/08 PHP
PHP实现导出带样式的Excel
2016/08/28 PHP
PHP模拟http请求的方法详解
2016/11/09 PHP
PHP判断是手机端还是PC端 PHP判断是否是微信浏览器
2017/03/15 PHP
PHP排序算法之快速排序(Quick Sort)及其优化算法详解
2018/04/21 PHP
Laravel框架自定义公共函数的引入操作示例
2019/04/16 PHP
php源码的安装方法和实例
2019/09/26 PHP
Gambit vs ForZe BO3 第三场 2.13
2021/03/10 DOTA
JavaScript在IE中“意外地调用了方法或属性访问”
2008/11/19 Javascript
dwz 如何去掉ajaxloading具体代码
2013/05/22 Javascript
jQuery中:nth-child选择器用法实例
2014/12/31 Javascript
js实现精美的银灰色竖排折叠菜单
2015/05/16 Javascript
在jQuery中使用$而避免跟其它库产生冲突的方法
2015/08/13 Javascript
jquery实现网页的页面平滑滚动效果代码
2015/11/02 Javascript
详解JavaScript的AngularJS框架中的作用域与数据绑定
2016/03/04 Javascript
解决Node.js使用MySQL出现connect ECONNREFUSED 127.0.0.1:3306的问题
2017/03/09 Javascript
jQuery 实现左右两侧菜单添加、移除功能
2018/01/02 jQuery
使用webpack-dev-server处理跨域请求的方法
2018/04/18 Javascript
vue实现侧边栏导航效果
2019/10/21 Javascript
vue中对象数组去重的实现
2020/02/06 Javascript
[03:55]显微镜下的DOTA2特别篇——430灰烬之灵神级操作
2014/06/24 DOTA
[01:44]《为梦想出发》—联想杯DOTA2完美世界全国高校联赛
2015/09/30 DOTA
python学习之第三方包安装方法(两种方法)
2015/07/30 Python
python版本的读写锁操作方法
2016/04/25 Python
独特的python循环语句
2016/11/20 Python
CSS3旋转——彩色扇子兼容firefox浏览器
2013/06/04 HTML / CSS
英国最大的化装舞会服装网站:Fancydress.com
2017/08/15 全球购物
精选鞋类、服装和配饰的全球领先目的地:Bodega
2021/02/27 全球购物
sort命令的作用和用法
2012/11/04 面试题
平安建设工作方案
2014/06/02 职场文书
《语言的突破》读后感3篇
2019/12/12 职场文书
pytorch实现ResNet结构的实例代码
2021/05/17 Python
python编程简单几行代码实现视频转换Gif示例
2021/10/05 Python
面试提问mysql一张表到底能存多少数据
2022/03/13 MySQL