【问题标题】:How does the spread syntax affect array splice扩展语法如何影响数组拼接
【发布时间】:2025-12-03 20:15:01
【问题描述】:

找到如下代码,不知道A和B有什么区别:

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

一个

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)

【问题讨论】:

标签: javascript arrays spread-syntax


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    首先,Statement A 和 Statement B 会产生不同的结果。

    Statement A 中,您将在位置 2 处插入一个数组 (["Lemon", "Kiwi"]) 作为数组元素,同时删除 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 更新原始数组
    • Statement A 在父字符串数组中插入 array (IE ["Lemon", "Kiwi"]) 而Statement B 在父字符串数组中插入 两个字符串 (IE 'Lemon', 'Kiwi') .

    【讨论】:

      【解决方案3】:

      A 将["Lemon", "Kiwi"] 视为一项并将其插入给定索引中

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

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

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

      像下面这样修改数组

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

      【讨论】:

        【解决方案4】:

        根据函数签名中的doc

        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");

        上面的代码你说添加"Lemon""Kiwi",从索引2而不删除0个项目。

        在这种情况下,2start 索引,deleteCount0item1"Lemon"item2"Kiwi"

        现在在 A:

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

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

        【讨论】:

          【解决方案5】:

          首先你需要了解拼接是如何工作的

          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"]);
          

          拼接会从索引 2 中取出水果,不删除任何内容(再次作为零)并添加其余参数,即“[”Lemon”,“Kiwi”]”

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

          希望对你有帮助。

          【讨论】:

            【解决方案6】:

            不使用展开,B 是:

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

            concat 有点混乱,也可以写成:

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

            或者:

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

            【讨论】: