更新整个对象,比如:
var x = {a:1}
function modify(obj) {
obj = {b:2}
}
modify(x)
console.log(x) // {a:1}
但是保持参考?我希望在函数外部修改对象。
我的具体情况是在我的函数中使用lodash.pick
:
if (whitelist) {
obj = _.pick(obj, whitelist)
}
我似乎找不到修改对象的pick
函数。有没有办法做到这一点,或者我需要开始返回对象的副本?
delete
旧对象中的所有内容,然后逐键添加新属性:
function modify(obj, newObj) {
Object.keys(obj).forEach(function(key) {
delete obj[key];
});
Object.keys(newObj).forEach(function(key) {
obj[key] = newObj[key];
});
}
var x = {a:1}
modify(x, {b:42})
document.write(JSON.stringify(x));
如果您想知道这是否是一个好主意,答案是否定的。构造一个新对象,从函数返回它并分配 - 这是一种非常可取的方式。
如果你包装你的对象并像这样更改修改函数,你可以实现这一点(不完全是你想要的),
var wrapper = {};
wrapper.x = {a:1};
function modify(obj, key) {
obj[key] = {b:2};
}
modify(wrapper, 'x');
console.log(wrapper.x); // {b:2}
/**
* Method to deep update the values of the source object from new object without changing source object reference
*
* @export
* @param {*} sourceObj
* @param {*} newObj
*/
export function updateObjKeepingRef(sourceObj: any, newObj: any): void {
Object.keys(newObj).forEach(key => {
// if value is object and instance is not Date
if (newObj[key] && typeof newObj[key] === 'object' && sourceObj[key] && !(newObj[key] instanceof Date)) {
updateObjKeepingRef(sourceObj[key], newObj[key]);
} else {
// updating properties
sourceObj[key] = newObj[key];
}
});
}
为什么修改不编辑 obj 引用的对象?
因为当你写的时候在里面修改:
obj = {b:2}
请注意,obj 是 modify 函数调用的局部变量。将创建一个新对象{b:2}
,局部变量 obj 现在引用此新对象。回想一下,变量 x 仍然引用{a:1}
对象。
如果 x 是全局变量,并且函数中没有名称的局部变量,那么您可以执行以下操作:
var x = {a:1};
function modify() {
x = {b:2}
}
modify();
console.log(x) // {b:2}
为什么上面的代码有效?
当你调用modify()时,它会尝试查看它是否有局部变量x,因为它找不到,所以它会在作用域链中查找。寻找此函数调用的下一个作用域是全局作用域,果然,我们有一个 x 变量。因此,现在设置了此全局变量 x 的值。
我遇到了这个问题。经过一些研究,我选择将objectTwo转换为JSON字符串,然后将objectOne替换为解析后的版本。换句话说:
var mObjectOne = { ExampleProperty: 10 };
var mObjectTwo = { ExampleProperty: 15 };
// I wanted mObjectOne to hold the same data as mObjectTwo, but keep a separate reference
var mObjectTwoAsJSON = JSON.stringify(mObjectTwo);
mObjectOne = JSON.parse(mObjectTwoAsJSON);
// Now the references are still different, as desired, but the object data has been updated.
谢谢
obj = JSON.parse(JSON.stringify(newObj))