扩展语法如何影响数组的splice方法?

38

我找到了下面的代码,但不知道A和B之间有什么区别:

var fruits = ["Banana", "Orange", "Apple", "Mango"];

A

fruits.splice(2,0,["Lemon", "Kiwi"]);

B

fruits.splice(...[2,0].concat(["Lemon", "Kiwi"]));

var fruits = ["Banana", "Orange", "Apple", "Mango"];
var A = fruits.splice(2, 0, ["Lemon", "Kiwi"]);
var B = fruits.splice(...[2, 0].concat(["Lemon", "Kiwi"]));

console.log(A)
console.log(B)


1
你应该学习splice运算符的概念 https://www.w3schools.com/jsref/jsref_splice.asp -@vuvu - bindi.raval
1
你可以从这里 https://lorenstewart.me/2017/01/22/javascript-array-methods-mutating-vs-non-mutating/ 查看 splice 属性。 - Feras Al Sous
2
这似乎更多是关于扩展运算符而不是splice。 - Teepeemm
2
如果在每个操作后记录 fruits 而不是记录 AB,您会注意到差异。 - Barmar
6个回答

41

首先,陈述A和陈述B将产生不同的结果。

声明A中,您正在将一个数组(["Lemon", "Kiwi"])作为数组元素插入到位置2,同时删除0个项目。因此,您正在在另一个字符串数组中的位置2插入一个字符串数组。

var fruits = ["Banana", "Orange", "Apple", "Mango"];


fruits.splice(2,0,["Lemon", "Kiwi"]);

console.log(fruits);

然而Statement B 更有趣。要完全理解它,首先像这样注销它的核心部分:

=>

console.log(...[2,0].concat(["Lemon", "Kiwi"]));  // basic array concatenation then spread

正如您所看到的它生成了2 0 Lemon Kiwi。 然后将其作为参数传递给fruits.splice(..here..)。 根据array#splice,它将在位置2输入两个字符串(Lemon和Kiwi),同时删除0个元素。

var fruits = ["Banana", "Orange", "Apple", "Mango"];

fruits.splice(...[2,0].concat(["Lemon", "Kiwi"]));
// is same as fruits.splice(2, 0, 'Lemon', 'Kiwi')

console.log(fruits);

注意:

  • array#splice 会更新原始数组
  • 语句A 将一个数组(例如 ["Lemon", "Kiwi"])插入到父字符串数组中,而 语句B两个字符串(例如 'Lemon','Kiwi')插入到父字符串数组中。

11
["Lemon", "Kiwi"] 视为一个项目,并将其插入到给定的索引位置。
["Banana", "Orange", ["Lemon", "Kiwi"], "Apple" , "Mango"];

B将[2,0]["Lemon", "Kiwi"]连接起来,然后将它们作为逗号分隔的参数传递给splice。

fruits.splice(2,0,"Lemon", "Kiwi");  

修改数组如下

["Banana", "Orange", "Lemon", "Kiwi", "Apple", "Mango"]

8

所有其他答案都正确描述了 splice 方法和展开运算符的行为,但没有人试图纠正您对结果的误解。

实际上,您看到的是splice方法的返回值,它是包含已删除元素的数组,在您的两个方法调用中,都没有删除任何元素。这就是为什么您得到一个空数组作为结果的原因。

要查看调用splice方法的行为,您需要在每次调用后记录fruits数组(而不是方法的返回值),在您的情况下,这并不是很有用,因为您对fruits数组的期望在第二次调用中不成立。


8
根据函数签名的文档

array.splice(start[, deleteCount[, item1[, item2[, ...]]]])

在 B 中:

fruits.splice(...[2,0].concat(["Lemon", "Kiwi"]));

因为 [2,0].concat(["Lemon", "Kiwi"]) 的意思是 [2,0,"Lemon", "Kiwi"]
所以使用扩展运算符 (...),fruits.splice(...[2,0,"Lemon", "Kiwi"]) 变成了 fruits.splice(2,0,"Lemon", "Kiwi")
以上代码的意思是在索引 2 处添加 "Lemon""Kiwi",同时不删除任何元素。
在这种情况下,2 是起始索引,deleteCount0item1"Lemon"item2"Kiwi"
现在看 A 部分:
fruits.splice(2,0,["Lemon", "Kiwi"]);

您正在说将["Lemon", "Kiwi"]从索引2开始添加,删除0个项目。 在这种情况下,2start索引,deleteCount0item1["Lemon", "Kiwi"]

6

首先,您需要了解splice如何工作

array.splice(start[, deleteCount[, item1[, item2[, ...]]]])

它需要起始索引(从零开始),要删除的元素数量,以及任何其他参数将添加到该起始索引。

现在你已经清楚了splice的用法,让我们逐步深入理解这些语句。

以下是需要翻译的内容:

fruits.splice(...[2,0].concat(["Lemon", "Kiwi"])); 

连接后变成

fruits.splice(...[2,0,"Lemon", "Kiwi"]);

扩散后,它变成了

fruits.splice(2,0,"Lemon", "Kiwi");

然后splice将从索引2开始获取水果,并删除没有给定的任何内容(即零),并添加其余的参数,即"Lemon"和"Kiwi"

所以你得到了["Banana", "Orange", "Lemon", "Kiwi", "Apple", "Mango"]

而在其他情况下:

fruits.splice(2,0,["Lemon", "Kiwi"]);

splice() 方法将从索引 2 开始获取水果,不删除任何元素(再次给出零),并添加剩余的参数,即 "["Lemon", "Kiwi"]"。

因此,您将获得 ["Banana", "Orange", ["Lemon", "Kiwi"], "Apple", "Mango"]

希望能帮到你。


4

如果不使用 spread,B 就是:

fruits.splice( 2, 0, "Lemon", "Kiwi" );

concat有点令人困惑,它也可以被写成:

fruits.splice( ...[ 2, 0 ], ...[ "Lemon", "Kiwi" ] );

或者:

fruits.splice( ...[ 2, 0, "Lemon", "Kiwi" ] );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接