javascript 在javascript中将对象数组复制到另一个数组中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16232915/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 03:49:53  来源:igfitidea点击:

Copying an array of objects into another array in javascript

javascriptarraysdeep-copy

提问by hAlE

How can I copy every element of an array (where the elements are objects), into another array, so that they are totally independent? I don't want changing an element in one array to affect the other.

如何将数组的每个元素(其中元素是对象)复制到另一个数组中,以便它们完全独立?我不想改变一个数组中的元素来影响另一个。

回答by T.J. Crowder

If the destination array doesn't exist yet...

如果目标数组尚不存在...

...you can use slice()or concat(). slice()is probably more idiomatic (you'll also see slice(0), but the default is 0, so...):

...您可以使用slice()concat()slice()可能更惯用(您还会看到slice(0),但默认值为 0,所以...):

var destinationArray = sourceArray.slice(); // Probably more idiomatic
// or
var destinationArray = sourceArray.concat();

As of ES2015 (aka ES6), there's also Array.from, which creates a new array from any array-like thing (including an actual array):

从 ES2015(又名 ES6)开始,还有Array.from,它从任何类似数组的东西(包括实际数组)创建一个新数组:

var destinationArray = Array.from(sourceArray);

(Array.fromcan be shimmed/polyfilled for older JavaScript engines.)

Array.from可以为旧的 JavaScript 引擎填充/填充。)

Also as of ES2015, you can use iterable spread notation and an array literal with any iterable (including an array):

同样从 ES2015 开始,您可以使用可迭代扩展符号和带有任何可迭代(包括数组)的数组文字:

var destinationArray = [...sourceArray];

After that, both arrays will have the same contents. Changing one array will not change the other. Naturally, if an array entry is an object, the entry for that object in both arrays will point to the same object; this isn't a "deep" copy.

之后,两个数组将具有相同的内容。改变一个阵列不会改变另一个。自然地,如果数组条目是一个对象,则两个数组中该对象的条目将指向同一个对象;这不是“深层”副本。

If the destination array exists...

如果目标数组存在...

...and you want to append the contents of the source array to it, you can use push:

...并且您想将源数组的内容附加到它,您可以使用push

destinationArray.push.apply(destinationArray, sourceArray);

That works by calling pushon the destination array using the applyfeature of JavaScript functions, which lets you specify the arguments for the function call as an array. pushwill push as many elements as it has arguments, so it ends up copying the elements from the source array to the destination array.

这是通过push使用applyJavaScript 函数的功能调用目标数组来实现的,该功能允许您将函数调用的参数指定为数组。push将推送尽可能多的元素,因为它有参数,所以它最终将元素从源数组复制到目标数组。

In ES2015 and later, you can make that cleaner with iterable spread notation (...):

在 ES2015 及更高版本中,您可以使用可迭代扩展符号 ( ...)使该内容更清晰:

destinationArray.push(...sourceArray);

Note that in both cases, the call is limited by the JavaScript engine's maximum number of function arguments (as of this writing, that's at least in the thousands for all major engines [and not in the hundreds of thousands, at least not for Chrome's V8]).

请注意,在这两种情况下,调用都受到 JavaScript 引擎最大函数参数数量的限制(在撰写本文时,对于所有主要引擎来说,这至少是数千个 [而不是数十万,至少对于 Chrome 的 V8 ])。

Here's an ES5 version:

这是一个 ES5 版本:

var source1, dest1, source2, dest2;

snippet.log("If dest doesn't exist yet:");
source1 = [1, 2, 3, 4];
dest1 = source1.slice(0);
snippet.log("[before change] source1 = " + source1.join(", "));
snippet.log("[before change] dest1 = " + dest1.join(", "));
source1[2] = "three";
dest1[3] = "four";
snippet.log("[after change] source1 = " + source1.join(", "));
snippet.log("[after change] dest1 = " + dest1.join(", "));

snippet.log("If dest already exists and we're just appending:");
source2 = [1, 2, 3, 4];
dest2 = ['a', 'b', 'c', 'd'];
snippet.log("[before append] source2 = " + source2.join(", "));
snippet.log("[before append] dest2 = " + dest2.join(", "));
dest2.push.apply(dest2, source2);
snippet.log("[before change] source2 = " + source2.join(", "));
snippet.log("[before change] dest2 = " + dest2.join(", "));
source2[2] = "three";
dest2[7] = "four";
snippet.log("[after change] source2 = " + source2.join(", "));
snippet.log("[after change] dest2 = " + dest2.join(", "));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

回答by jsbisht

Easy way to get this working is using:

使这项工作的简单方法是使用:

var cloneArray = JSON.parse(JSON.stringify(originalArray));

I have issues with getting arr.concat()or arr.splice(0)to give a deep copy. Above snippet works perfectly.

我在获取arr.concat()arr.splice(0)提供深层副本时遇到问题。上面的片段完美地工作。

回答by Ilya

var clonedArray = array.concat();

回答by MauricioLeal

A great way for cloning an array is with an array literaland the spread operator. This is made possible by ES2015.

克隆数组的一个好方法是使用数组字面量展开运算符ES2015使这成为可能。

const objArray = [{name:'first'}, {name:'second'}, {name:'third'}, {name:'fourth'}];

const clonedArr = [...objArray];

console.log(clonedArr) // [Object, Object, Object, Object]

You can find this copy option in MDN's documentation for spread operatorshttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Copy_an_array

您可以在 MDN 的扩展运算符文档中找到此复制选项https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Copy_an_array

It is also an Airbnb'sbest practice. https://github.com/airbnb/javascript#es6-array-spreads

这也是Airbnb的最佳实践。https://github.com/airbnb/javascript#es6-array-spreads

Note: Typically the spread operators in ES2015 goes one level deep while copying an array. Therefore, they are unsuitable for copying multidimensional arrays.

注意:通常 ES2015 中的扩展运算符在复制数组时会深入一层。因此,它们不适合复制多维数组。

回答by Tran Vu Dang Khoa

There are two important notes.

有两个重要的注意事项。

  1. Using array.concat()does not work using Angular 1.4.4 and jQuery 3.2.1 (this is my environment).
  2. The array.slice(0)is an object. So if you do something like newArray1 = oldArray.slice(0); newArray2 = oldArray.slice(0), the two new arrays will reference to just 1 array and changing one will affect the other.
  1. 使用array.concat()Angular 1.4.4 和 jQuery 3.2.1(这是我的环境)不起作用。
  2. array.slice(0)是一个对象。因此,如果您执行类似的操作newArray1 = oldArray.slice(0); newArray2 = oldArray.slice(0),两个新数组将仅引用 1 个数组,更改一个数组会影响另一个数组。

Alternatively, using newArray1 = JSON.parse(JSON.stringify(old array))will only copy the value, thus it creates a new array each time.

或者, usingnewArray1 = JSON.parse(JSON.stringify(old array))只会复制值,因此每次都会创建一个新数组。

回答by Veikko Karsikko

If you want to keep reference:

如果您想保留参考:

Array.prototype.push.apply(destinationArray, sourceArray);

Array.prototype.push.apply(destinationArray, sourceArray);

回答by bean5

I suggest using concat()if you are using nodeJS. In all other cases, I have found that slice(0)works fine.

concat()如果您使用的是 nodeJS,我建议使用。在所有其他情况下,我发现slice(0)效果很好。