Js数组slice⽤法⼤合集
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);
}js arguments
这看起来可⾏,但如果你试着去做,你就会得到错误:
> 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)
Line (repl.js:440:10)
at emitOne (events.js:120:20)
it (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, at(remainingArgs));
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。