为什么使用切片克隆列表会影响原始列表

Why does Cloning list using slice effects the original list

本文关键字:列表 影响 原始 切片 为什么      更新时间:2023-09-26

下面是我将数组中的对象更改为字符串的代码。不明白为什么会影响原来的数组。切片应该是克隆数组,如果我是对的吗?

var cloned = $scope.selected.items.slice(0);
cloned.forEach(function (cluster) {
  cluster.status = cluster.status.name;
})
ObjToPost.MO = cloned;
console.log("consoling the cluster list", ObjToPost.MO);
console.log("consoling the original cluster list", $scope.selected.items);

安慰后两个数组是相同的

引用Array.prototype.slice的MDN,

slice()方法返回一个数组部分的浅拷贝到一个新的数组对象中。

这里重要的词是"shallow copy"。它创建一个新的Array,并使数组中的元素指向同一个对象。

在您的示例中,即使在切片之后,原始数组和克隆数组中的每个数组元素都在内存中引用相同的集群对象。

Original                        Cloned
+-----+                        +-----+
|  0  |--> Cluster Object 1 <--|  0  |
+-----+                        +-----+
|  1  |--> Cluster Object 2 <--|  1  |
+-----+                        +-----+
|  2  |--> Cluster Object 3 <--|  2  |
+-----+                        +-----+

由于所有对应的元素都引用相同的对象,因此在一个数组中更改它也会反映在另一个数组中。

注意:如果你正在寻找一种方法来做深度复制,那么你可能需要检查这个问题

正如@thefourtheye所解释的,您正在创建数组的浅副本。要深度复制数组项,并修改状态,你可以使用array .prototype.map和angular.merge():

ObjToPost.MO = $scope.selected.items.map(function(cluster) {
    return angular.merge({}, cluster, { status: cluster.status.name }); // create a deep copy of each item, and override status with status.name
});