将JavaScript中的数组复制到另一个数组时:

var arr1 = ['a','b','c'];
var arr2 = arr1;
arr2.push('d');  //Now, arr1 = ['a','b','c','d']

我意识到arr2指的是与arr1相同的数组,而不是一个新的独立数组。如何复制阵列以获得两个独立的阵列?


当前回答

您可以使用阵列排列。。。复制阵列。

const itemsCopy=[…items];

此外,如果要创建一个新数组,现有数组是其中的一部分:

var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes'];

现在所有主流浏览器都支持数组排列,但如果您需要更旧的支持,请使用typescript或babel并编译到ES5。

有关点差的更多信息

其他回答

正如我们在Javascript中所知道的那样,数组和对象都是通过引用的,但是我们可以用什么方法复制数组而不改变后面的原始数组呢?

这里有几种方法:

假设我们在您的代码中有这个数组:

var arr = [1, 2, 3, 4, 5];

1) 在函数中循环数组并返回一个新数组,如下所示:

 function newArr(arr) {
      var i=0, res = [];
      while(i<arr.length){
       res.push(arr[i]);
        i++;
       }
   return res;
 }

2) 使用slice方法,slice用于对数组的一部分进行切片,它将在不接触原始数组的情况下对数组的某些部分进行切片。在切片中,如果不指定数组的开始和结束,它将对整个数组进行切片,并基本上制作数组的完整副本,因此我们可以很容易地说:

var arr2 = arr.slice(); // make a copy of the original array

3) 还有contact方法,这是用于合并两个数组,但我们可以只指定其中一个数组,然后这基本上会复制新接触数组中的值:

var arr2 = arr.concat();

4) 另外,不建议使用stringify和parse方法,但这是复制Array和Objects的一种简单方法:

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

5) Array.from方法,这不受广泛支持,使用前请检查不同浏览器中的支持:

const arr2 = Array.from(arr);

6) ECMA6方式,也不完全支持,但babelJs可以帮助您,如果您想转换:

const arr2 = [...arr];

我个人认为Array.from是一个更具可读性的解决方案。顺便说一句,请注意它的浏览器支持。

//克隆设x=[1,2,3];设y=数组.来自(x);console.log({y});//深层克隆让clone=arr=>Array.from(arr,item=>Array.isArray(item)?克隆(项目):项目);x=[1,[],[[]]];y=克隆(x);console.log({y});

在Javascript中,深度复制技术依赖于数组中的元素。让我们从这里开始。

三种类型的元素

元素可以是:文字值、文字结构或原型。

// Literal values (type1)
const booleanLiteral = true;
const numberLiteral = 1;
const stringLiteral = 'true';

// Literal structures (type2)
const arrayLiteral = [];
const objectLiteral = {};

// Prototypes (type3)
const booleanPrototype = new Bool(true);
const numberPrototype = new Number(1);
const stringPrototype = new String('true');
const arrayPrototype = new Array();
const objectPrototype = new Object(); // or `new function () {}

从这些元素中,我们可以创建三种类型的数组。

// 1) Array of literal-values (boolean, number, string) 
const type1 = [ true, 1, "true" ];

// 2) Array of literal-structures (array, object)
const type2 = [ [], {} ];

// 3) Array of prototype-objects (function)
const type3 = [ function () {}, function () {} ];

深度复制技术取决于三种阵列类型

根据数组中元素的类型,我们可以使用各种技术进行深度复制。

深度复制技术

基准

https://www.measurethat.net/Benchmarks/Show/17502/0/deep-copy-comparison

文字值数组(类型1)[…myArray]、myArray.splice(0)、myArrax.slice()和myArray.concat()技术可用于深度复制仅具有文字值(布尔值、数字和字符串)的数组;其中slice()在Chrome中具有最高的性能,并且扩展。。。在Firefox中具有最高的性能。文本值(类型1)和文本结构(类型2)的数组JSON.parse(JSON.stringify(myArray))技术可用于深度复制文本值(布尔值、数字、字符串)和文本结构(数组、对象),但不能复制原型对象。所有数组(类型1、类型2、类型3)Lo-dash-cloneDeep(myArray)或jQuery-extend(true,[],myArray)技术可用于深度复制所有数组类型。其中Lodash cloneDeep()技术具有最高的性能。对于那些避免使用第三方库的用户,下面的自定义函数将深度复制所有数组类型,性能低于cloneDeep(),性能高于extend(true)。

function copy(aObject) {
  // Prevent undefined objects
  // if (!aObject) return aObject;

  let bObject = Array.isArray(aObject) ? [] : {};

  let value;
  for (const key in aObject) {

    // Prevent self-references to parent object
    // if (Object.is(aObject[key], aObject)) continue;
    
    value = aObject[key];

    bObject[key] = (typeof value === "object") ? copy(value) : value;
  }

  return bObject;
}

所以要回答这个问题。。。

问题

var arr1 = ['a','b','c'];
var arr2 = arr1;

我意识到arr2指的是与arr1相同的数组,而不是一个新的独立数组。如何复制阵列以获得两个独立的阵列?

答复

因为arr1是一个文本值数组(布尔值、数字或字符串),所以可以使用上面讨论的任何深度复制技术,其中slice()和spread。。。具有最高的性能。

arr2 = arr1.slice();
arr2 = [...arr1];
arr2 = arr1.splice(0);
arr2 = arr1.concat();
arr2 = JSON.parse(JSON.stringify(arr1));
arr2 = copy(arr1); // Custom function needed, and provided above
arr2 = _.cloneDeep(arr1); // Lo-dash.js needed
arr2 = jQuery.extend(true, [], arr1); // jQuery.js needed

从ES2015开始,

var arr2 = [...arr1];

您可以通过以下方式实现:arr2=arr1.map(x=>Object.assign({},x));