
slice
方法是JS语言中最强大、最常用的内建函数之一。
- 函数式编程,尤其是高阶函数,与数据列表密切配合
- 函数式编程需要纯函数,即不会产生副作用或修改输入数据的函数
slice
方法符合这两个标准。
slice
方法可以在不修改原始列表的情况下创建列表子集的浅拷贝。
因此,它为编写函数式 JS 提供了一个关键的构建块。
slice
方法,探索它的8种不同用法。
slice
方法不要与
splice
方法混淆,
splice
方法会修改原始数组。
slice
方法的基础知识。
slice
是数组上的一个方法,它最多有两个参数:
arr.slice([begin[, end]])
slice(-2)
表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。
如果省略
begin
,则
slice
从索引 0 开始。
slice
会提取原数组中索引从
begin
到
end
的所有元素(包含begin,但不包含end)。
slice(1,4)
提取原数组中的第二个元素开始直到第四个元素的所有元素 (索引为 1, 2, 3的元素)。
slice(-2,-1)
表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。
end
被省略,则
slice
会一直提取到原数组末尾。
如果
end
大于数组长度,
slice
也会一直提取到原数组末尾。
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
的另一种使用方法是获取数组的末尾,利用的是
负索引
从末尾开始计数。
const last3 = arr.slice(-3)
用法4:获取数组的前n个
end
。
slice
方法返回一个从
begin
开始但不包括
end
的集合。
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);
}
处理类似数组的对象
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:将任意长度多余的参数强制转换为数组
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
,也可以译作“局部应用”、“部分应用”、“偏应用”
函数式编程中的另一种常见模式是所谓的偏函数应用:
将函数预先应用于函数,然后返回一个新函数。
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));
}
}


版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/cjjbc/64496.html