在Angular中深度复制对象

Deep copying objects in Angular

AngularJS具有从angular.copy()到深度复制对象和数组的功能。

角也有类似的东西吗?


您还可以使用:

JSON.parse(JSON.stringify(Object))

如果它在您的范围内,它在每个角度组件、指令等中,也在每个节点环境中。

除非您有一个循环引用,否则它应该可以工作,并且将有效地取消您对原始对象的变量引用的关联。


另一种选择是实现您自己的功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 * Returns a deep copy of the object
 */
public static deepCopy(oldObj: any) {
    var newObj = oldObj;
    if (oldObj && typeof oldObj ==="object") {
        if (oldObj instanceof Date) {
           return new Date(oldObj.getTime());
        }
        newObj = Object.prototype.toString.call(oldObj) ==="[object Array]" ? [] : {};
        for (var i in oldObj) {
            newObj[i] = this.deepCopy(oldObj[i]);
        }
    }
    return newObj;
}


这个问题不是我如何在Angular2中使用Angular.copy的复制品,因为OP询问的是深度复制对象。链接的答案建议使用object.assign(),它不会进行深度复制。

实际上,使用angular2并不限制您使用其他库(如jquery)使用$.clone()函数来深度复制对象,或使用lodash使用uuclonedeep()来深度复制对象。

最常见的库通过typings cli工具提供了它们的类型,因此即使从typescript中得到,您也可以无缝地使用您想要的任何东西。

另请参见:在javascript中深度克隆对象最有效的方法是什么?


您可以使用lodash的clonedeep方法,以一定角度来处理一个物体:

yarn add lodashnpm install lodash安装Lodash。

在组件中,导入cloneDeep并使用它:

1
2
3
import * as cloneDeep from 'lodash/cloneDeep';
...
clonedObject = cloneDeep(originalObject);

它只添加了18kb到您的构建中,非常值得。

我在这里也写了一篇文章,如果你需要更多的了解为什么使用罗达什的克隆edep。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Create helper class with name deepCopy.ts

/*
* DeepCopy class helps to copy an Original Array or an Object without impacting on original data
*/

export class DeepCopy {

  static copy(data: any) {
    let node;
    if (Array.isArray(data)) {
      node = data.length > 0 ? data.slice(0) : [];
      node.forEach((e, i) => {
        if (
          (typeof e === 'object' && e !== {}) ||
          (Array.isArray(e) && e.length > 0)
        ) {
          node[i] = DeepCopy.copy(e);
        }
      });
    } else if (data && typeof data === 'object') {
      node = data instanceof Date ? data : Object.assign({}, data);
      Object.keys(node).forEach((key) => {
        if (
          (typeof node[key] === 'object' && node[key] !== {}) ||
          (Array.isArray(node[key]) && node[key].length > 0)
        ) {
          node[key] = DeepCopy.copy(node[key]);
        }
      });
    } else {
      node = data;
    }
    return node;
  }
}

根据需要导入deepcopy文件,并按以下代码使用deepcopy.copy(arg);,这里arg将对象或数组


如果源是对象数组,请使用map:

1
let cloned = source.map(x => Object.assign({}, x));

1
2
3
let cloned = source.map((x) => {
                return { ...x };
             });


我在typescript中创建了一个非常简单的函数,它接受所有可能的输入,并提供该对象的深度克隆副本。

希望它能帮助别人。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  public deepCopy(obj) {

    var clonedObject: any;

    if (obj instanceof Array) {
        var itemArray = Object.assign([], obj);
        clonedObject = itemArray;

        for (var j = 0; j < clonedObject.length; j++) {
            clonedObject[j] = this.deepCopy(clonedObject[j]);
        }

        return clonedObject;
    }
    else if (typeof obj === 'number' || typeof obj == 'string') {
        return obj
    }
    else {


        var item = Object.assign({}, obj);
        clonedObject = item;

        let allKeys = Object.keys(clonedObject);

        for (var i = 0; i < allKeys.length; i++) {
            if (clonedObject[allKeys[i]] instanceof Array) {
                //If the calue is Array
                clonedObject[allKeys[i]] = this.deepCopy(clonedObject[allKeys[i]]);
            }
            else if (clonedObject[allKeys[i]] instanceof Date) {
                clonedObject[allKeys[i]] = new Date(clonedObject[allKeys[i]].valueOf());
            }
            else if (clonedObject[allKeys[i]] instanceof Object){
                //if the value is JOBJECT.
                clonedObject[allKeys[i]] = this.deepCopy(clonedObject[allKeys[i]]);
            }
        }
        return clonedObject;
    }


}