角度/打字稿,变量有问题

时间:2019-07-09 08:34:49

标签: angular typescript

有我的问题:

我有一个将元素添加到数组(A)的函数,要添加的元素来自参数。然后,当我修改数组(A)中的该元素时,它也会同时修改用作参数的元素。

看起来像这样:

addTemplates(nTemplate){
    let k = nTemplate;
    k.id=this.templates.length+1;
    this.templates.push(k);
    this.emitTemplateSubject();
  }
  
  //when I use the function:
  
  let aObject={id:1, sth:"aa", sthE:"bb"}
  addTemplate(aObject);
  
  
  //then  aObject.id is also change.

这可能很正常,但如何避免将更改应用于'aObject'?

4 个答案:

答案 0 :(得分:2)

您必须创建对象的副本,然后将其发送给函数

let newObject = Object.assign({}, aObject);
addTemplate(newObject );

这是因为传递对象时,它是作为参考传递的。您需要的是传递数据,为此您需要创建对象的副本并将其发送给函数。

答案 1 :(得分:1)

使用this.templates.push(k);,您可以向k添加templates的引用,而不是副本。因此,当您修改数组中引用的属性时,您正在修改的对象与直接修改k时相同。

一个简单的示例,它显示了引用和副本之间的区别(在这种情况下,我正在使用JSON.parse(JSON.stringify(...))创建副本,对于实际的真实情况,我不建议这样做生活项目):

const original = {"property":"value"};
const reference = original;
const copy = JSON.parse(JSON.stringify(original));

const array = [reference, copy];

array[0].property = 'new value for reference';
array[1].property = 'new value for copy';

console.log(reference.property === original.property);
console.log(copy.property !== original.property);

如果对象较浅,则可以简单地使用散布运算符(this.templates.push({...k});)创建副本。

如果您将对象作为k的属性,这意味着将在副本you'd need to deep-clone k.

中引用它们

答案 2 :(得分:0)

您可以使用spread运算符,并输入以下内容:

let aObject={id:1, sth:"aa", sthE:"bb"}
addTemplate({... aObject});

答案 3 :(得分:0)

您可以尝试以下类似方法,并使用assign关键字创建新对象,而不是分配参考。

let aObject = {
  id: 1, sth: "aa", sthE: "bb"
}
addTemplates(aObject);


function addTemplates(nTemplate) {
  let k  = Object.assign({}, nTemplate);
  k.id=this.templates.length+1;
  this.templates.push(k);
  this.emitTemplateSubject();
}