预期成绩
我编写了一个函数,以获取简单的对象文字,并对其重新格式化,如本例所示:
var original = { a: 1, b: true, c: "a string" }
// run through function ...
var result = {
a: { type: "int", val: 1 },
b: { type: "bit", val: 1 },
c: { type: "varchar(250)", val: "a string" }
}
当前解决方案
该函数起作用,使用
for ... in
循环遍历原始对象并基于原始数据构建新对象。function change (data) {
function loop (d) {
var orig = d;
var end = d;
for (var key in orig) {
var property = {
type: "test",
val: orig[key]
};
end[key] = property;
}
return end;
}
// create object using loop & return
var p = loop(data);
return p;
}
实际结果
但是,此功能还改变了传入的原始对象,我似乎无法弄清楚原因。
var original = { a: 1, b: true, c: "a string" }
// run through function ...
var result = change(original);
console.log(result); // => {
// a: { type: "int", val: 1 },
// b: { type: "bit", val: 1 },
// c: { type: "varchar(250)", val: "a string" }
// }
console.log(original); // => {
// a: { type: "int", val: 1 },
// b: { type: "bit", val: 1 },
// c: { type: "varchar(250)", val: "a string" }
// }
// instead of expected:
// { a:1, b:true, c:"a string" }
我猜想这与我对javascript范围的不完全了解有关,可能与原型继承有关(我肯定需要了解更多信息),但是在这一点上,我不确定从哪里真正开始了解这里发生了什么。当我将其与我对JavaScript的副作用产生的简单理解进行比较时,我会感到非常困惑:
var a = 1;
var b = a;
console.log(a) // => 1
console.log(b) // => 1
b = 2
console.log(a) // => 1
console.log(b) // => 2
该功能按原样运行,并且在我的程序其余部分中正在做我需要做的事情,但是这个问题确实让我感到困扰,因为我不了解这里发生了什么。
最佳答案
在Javascript中,当您决定在函数中将对象作为参数传递时,该对象将作为对原始对象的引用,并且也会对其进行突变。
如果您像只读一样处理它,它将作为常规参数(通过值传递)
对于平坦的对象(不包含嵌套对象),可以使用Object.assign
(具有可用polyfill的Es6功能)
let obj1 = { a: 1};
let obj2 = Object.assign({}, obj1);
对于更复杂的对象,我建议您使用一些库方法,例如lodash的
_.cloneDeep
// you have to include lodash.js in your page
let obj1 = { a: 1};
let obj2 = _.cloneDeep(obj1);
或jQuery的
$.extend
// you have to include jquery.js in your page
let obj1 = { a: 1};
let obj2 = $.extend(true, {}, obj1);
关于javascript - 影响新对象的一面正在更改原始对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38603734/