如何在不改变原始参数数组的情况下操作传递给函数的数组? JavaScript的

时间:2017-05-01 22:14:39

标签: javascript arrays arguments

我想使用传递给函数的数组,同时保持原始数组不变。这是一个简单的问题示例。

function whyDoesArrChange(arr) {
   var newArr = arr;
   newArr.push(4);

   return arr;
 }

 console.log(whyDoesArrChange([1,2,3]));
// OUT: [1,2,3,4]

我希望只更改newArr,但是arr(来自参数)也会返回推送值(返回[1,2,3,4])。我怎么能避免这个?真诚地感谢你。

4 个答案:

答案 0 :(得分:5)

将数组传递给函数时,该数组的值是引用,您必须克隆它才能破坏引用。

有多种方法可以实现这一目标:

1 - 使用.slice();

var newArr = arr.slice();

2 - 使用.concat

var newArr = arr.concat([]);

3 - 使用JSON.parse& JSON.stringify

var newArr = JSON.parse(JSON.stringify(arr));

您可以查看更多方法,了解它们在我找到的jsperf中的效果。

答案 1 :(得分:1)

在JavaScript中,当您使用(=)将值从变量赋值给另一个变量时,您只需传递整个变量,因此每次更改一个或另一个变量时,另一个变量也会发生变化。

根据您的问题,对我有用的最佳方法是将原生.slice()JavaScript方法用于数组对象。对于您的代码:

function whyDoesArrChange(arr) {
    var newArr = arr.slice();
    newArr.push(4);
    return arr;
}

答案 2 :(得分:1)

虽然马科斯的回答是正确的,但毫无疑问。可以使用更多纯数组函数(纯函数是一种不会改变其范围之外的数据的函数)。

通常情况下,如果您想对阵列执行多项操作,我会选择Marcos的答案,然后像往常一样进行这些更改。但是当情况并非如此时,以下信息可能会有用:

  1. 添加:arr.concat([1]);
  2. 子阵列(i到j):arr.slice(i, j + 1);
  3. 删除(i到j):arr.slice(0, i).concat(arr.slice(j + 1));
  4. 此外,filtermap是纯函数,不会改变数组。

答案 3 :(得分:0)

因为引用类型(数组和对象)在作为参数传递时可以在函数内部进行修改,而原始类型(数字,字符串,布尔值等)不会。

您可以使用.slice()对数组进行浅层复制并处理该数组,或者使用.concat方法返回一个新数组。

function whyDoesArrChange(arr) {
   return arr.concat(4);
 }