我在JavaScript中遇到一种奇怪的情况,我正在创建一个对象,然后将其作为参数传递给一个函数,该函数随后更新值,然后返回新的更新后的对象。
function objBuild() {
var obj_old = {}; // original object
var obj_new = {}; // updated object
// set values for original object
obj_old.val01 = "val01_old";
obj_old.val02 = "val02_old";
obj_old.val03 = "val03_old";
// set values for new object using
// the original object as a template
obj_new = objUpdate(obj_old);
console.log(obj_old); // this shows obj_new data which I don't want
console.log(obj_new); // this shows obj_new data which I want
}
function objUpdate(obj) {
obj.val03 = "val03_new";
return obj;
}
我期望新的Object会使用新的Value进行更新,但是旧的Object也会更新。
也许该函数将旧的Object作为参考,即使我返回一个单独的值,它也记得发生了什么事?
我不确定,但是是否可以保留旧对象完整?
答案 0 :(得分:1)
您实际上不是在创建新对象,而是将旧对象设置为新对象。所以您是正确的,仍在引用旧对象值。
如果您要创建一个新对象,并且没有任何嵌套对象,则可以使用Object.assign()
。这将生成对象的浅表副本。您可以执行以下操作:
obj_new = objUpdate(Object.assign({}, obj_old));
这将创建一个具有旧对象可枚举属性的新对象。
如果您有嵌套的对象,这些对象仍将通过引用进行复制,所以我将遍历该对象并以这种方式复制属性。
答案 1 :(得分:1)
请记住,对象(包括数组)是通过引用传递的,而字符串,布尔值和数字是通过值传递的。
在这里,您正在传递对象(通过引用),因此它正在修改旧对象的值。旧对象和新对象都指向相同的值。
function objBuild() {
var obj_old = {}; // original object
var obj_new = {}; // updated object
// set values for original object
obj_old.val01 = "val01_old";
obj_old.val02 = "val02_old";
obj_old.val03 = "val03_old";
// set values for new object using
// the original object as a template
obj_new = objUpdate(obj_old);
console.log(obj_old); // this shows obj_new data which I don't want
console.log(obj_new); // this shows obj_new data which I want
}
function objUpdate(obj_old) {
var obj = JSON.parse(JSON.stringify(obj_old));
obj.val03 = "val03_new";
return obj;
}
objBuild();
答案 2 :(得分:1)
请阅读:Is JavaScript a pass-by-reference or pass-by-value language?
在javascript中,对象是“技术上”通过“引用”传递的。因此,原始值会被更改,因为obj
实际上是原始对象。
您需要克隆对象,并且存在关于“如何”执行操作的广泛方案,因为对象可能是浅拷贝或深拷贝。在此处详细了解:What is the most efficient way to deep clone an object in JavaScript? 此处:How do I correctly clone a JavaScript object?
无论如何,要解决您的问题,只需在全新的对象上使用Object.assign
复制原始对象的值,就您的情况而言,这已经足够了,尽管我建议您阅读以上文章以学习何时以及如何正确复制对象。
function objBuild() {
var obj_old = {}; // original object
var obj_new = {}; // updated object
// set values for original object
obj_old.val01 = "val01_old";
obj_old.val02 = "val02_old";
obj_old.val03 = "val03_old";
// set values for new object using
// the original object as a template
obj_new = objUpdate(obj_old);
console.log(obj_old); // this shows obj_new data which I don't want
console.log(obj_new); // this shows obj_new data which I want
}
function objUpdate(obj) {
var _cloned = Object.assign({}, obj);
_cloned.val03 = "val03_new";
return _cloned;
}
objBuild();