关于javascript:数组深度复制 angular 2+typescript

Deep copy an array in Angular 2 + TypeScript

我有一个作为输入的对象数组。我们称之为content

当尝试进行深度复制时,它仍然引用上一个数组。

我需要复制该输入数组,并更改复制部分的一个属性。

这么久以来,我尝试过各种不成功的方法。

ES6方式:

1
2
3
4
5
public duplicateArray() {
  arr = [...this.content]
  arr.map((x) => {x.status = DEFAULT});
  return this.content.concat(arr);
}

slice方式:

1
2
3
4
5
public duplicateArray() {
  arr = this.content.slice(0);
  arr.map((x) => {x.status = DEFAULT});
  return this.content.concat(arr);
}

在这两个数组中,数组中的所有对象都有status: 'Default'

在角度2中,深度复制阵列的最佳方法是什么?


检查一下:

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


简单的:

1
let objCopy  = JSON.parse(JSON.stringify(obj));


这对我很有效:

1
this.listCopy = Object.assign([], this.list);


我找到的唯一解决方案(在发布问题后几乎立刻)是循环遍历数组并使用Object.assign()

这样地:

1
2
3
4
5
6
7
8
public duplicateArray() {
  let arr = [];
  this.content.forEach((x) => {
    arr.push(Object.assign({}, x));
  })
  arr.map((x) => {x.status = DEFAULT});
  return this.content.concat(arr);
}

我知道这不是最佳选择。我想知道有没有更好的解决办法。


使用lodash的clonedeep方法可以清晰地复制内部有嵌套对象的深度复制对象。

对于角度,可以这样做:

yarn add lodashnpm install lodash安装Lodash。

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

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

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

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


这是Daria的建议(参见对问题的评论),它从typescript 2.1开始工作,基本上从数组中克隆每个元素:

1
this.clonedArray = theArray.map(e => ({ ... e }));


这是我自己的。不适用于复杂的情况,但对于简单的对象数组来说,这就足够好了。

1
2
3
4
5
6
7
  deepClone(oldArray: Object[]) {
    let newArray: any = [];
    oldArray.forEach((item) => {
      newArray.push(Object.assign({}, item));
    });
    return newArray;
  }

或者,您可以使用github项目ts deepcopy(它也可以在NPM上使用)来克隆您的对象,或者只包括下面的代码片段。

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
/**
 * Deep copy function for TypeScript.
 * @param T Generic type of target/copied value.
 * @param target Target value to be copied.
 * @see Source project, ts-deepcopy https://github.com/ykdr2017/ts-deepcopy
 * @see Code pen https://codepen.io/erikvullings/pen/ejyBYg
 */

export const deepCopy = <T>(target: T): T => {
  if (target === null) {
    return target;
  }
  if (target instanceof Date) {
    return new Date(target.getTime()) as any;
  }
  if (target instanceof Array) {
    const cp = [] as any[];
    (target as any[]).forEach((v) => { cp.push(v); });
    return cp.map((n: any) => deepCopy(n)) as any;
  }
  if (typeof target === 'object' && target !== {}) {
    const cp = { ...(target as { [key: string]: any }) } as { [key: string]: any };
    Object.keys(cp).forEach(k => {
      cp[k] = deepCopy(cp[k]);
    });
    return cp as T;
  }
  return target;
};

1
2
let originalArray :string[]  = ['one', 'two', 'Sc-fi'];
let cloneArray :string[]  = originalArray.concat([]);

可以使用jquery进行深度复制:

1
2
3
4
5
var arr =[['abc'],['xyz']];
var newArr = $.extend(true, [], arr);
newArr.shift().shift();

console.log(arr); //arr still has [['abc'],['xyz']]