繁体   English   中英

JavaScript 在对象中设置值

[英]JavaScript Set value in object

我对 JS 很陌生,发生了一些奇怪的事情。 我尝试在一个对象中设置不同的值,并且表的所有值都被更改了似乎问题来自通过对象调用“materialStd”创建对象

obj.line[0].material.flow of 应该保持在 123 而不是 3

有人能够解释那里发生的事情吗谢谢

https://jsfiddle.net/vx6fno9p/5/

 var materialStd = { flow: 123, name: 'Raoul' }; var obj = { id: 0, line: [{ id: 1, material: materialStd }, { id: 2, material: materialStd }, { id: 3, material: materialStd } ] } testerror(); function testerror() { console.info(obj); //On appel une fct test console.log('' + obj.line[0].material.flow); console.log('' + obj.line[1].material.flow); console.log('' + obj.line[2].material.flow); test(obj); console.log('' + obj.line[0].material.flow); console.log('' + obj.line[1].material.flow); console.log('' + obj.line[2].material.flow); } function test(objetTraiter) { // objetTraiter.line[0].material.flow=1; // objetTraiter.line[1].material.flow=2; objetTraiter.line[2].material.flow = 3; console.log('' + objetTraiter.line[0].material.flow); console.log('' + objetTraiter.line[1].material.flow); console.log('' + objetTraiter.line[2].material.flow); }

你的问题是关于参考,当你写:

line: [
    {id:1, material:materialStd},
    {id:2, material:materialStd},
    {id:3, material:materialStd}
]

相同的对象放在 3 个位置。 因此,当您执行objetTraiter.line[2].material.flow=3 ,它会更改 3 个线对象中存在的对象。

在 Javascript 中,要不保留相同引用的情况下克隆数据对象,我们可以使用JSON.parse(JSON.stringify(obj)) 参考

所以你可以使用:

line: [
    {id:1, material: JSON.parse(JSON.stringify(materialStd))},
    {id:2, material: JSON.parse(JSON.stringify(materialStd))},
    {id:3, material: JSON.parse(JSON.stringify(materialStd))}
]

当您使用material: materialStd ,您不会获得对象materialStd的副本,而只是一个引用。

所以当你在这里更新objetTraiter.line[2].material.flow=3;

这实际上改变了materialStd对象,因为objetTraiter.line[2].material引用了materialStd而不是一个独立的对象。

您必须根据需要克隆对象。 有多种方法可以克隆对象, JSON.parse(JSON.stringify(obj))就是其中之一。

请参阅如何正确克隆 JavaScript 对象? 有关对象克隆的更多信息。

您可能会在下面的示例中找到您想要的结果

 var materialStd = { flow: 123, name: 'Raoul' }; function cloneObject(obj) { return JSON.parse(JSON.stringify(obj)) } var obj = { id: 0, line: [{ id: 1, material: cloneObject(materialStd) // clones }, { id: 2, material: cloneObject(materialStd) }, { id: 3, material: cloneObject(materialStd) } ] } testerror(); function testerror() { console.info(obj); //On appel une fct test console.log('' + obj.line[0].material.flow); console.log('' + obj.line[1].material.flow); console.log('' + obj.line[2].material.flow); test(obj); console.log('' + obj.line[0].material.flow); console.log('' + obj.line[1].material.flow); console.log('' + obj.line[2].material.flow); } function test(objetTraiter) { // objetTraiter.line[0].material.flow=1; // objetTraiter.line[1].material.flow=2; objetTraiter.line[2].material.flow = 3; console.log('' + objetTraiter.line[0].material.flow); console.log('' + objetTraiter.line[1].material.flow); console.log('' + objetTraiter.line[2].material.flow); }

因为通过引用传递

 var materialStd={flow:123, name:'Raoul'}; var obj={ id:0, line:[ {id:1, material:materialStd}, {id:2, material:materialStd}, {id:3, material:materialStd}] } // Compare them console.log( (obj.line[0].material === obj.line[1].material) && (obj.line[1].material === obj.line[2].material) ) // true

正如其他答案所建议的那样,在obj.line[index]["material"] 中为您的预期行为克隆一个新的参考

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM