替换对象值而不替换引用


如何

更新整个对象,比如:

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}

请注意,objmodify 函数调用的局部变量。将创建一个新对象{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))

最新更新