替换对象值而不替换引用

时间:2014-11-16 13:55:00

标签: javascript object reference

如何更新整个对象,比如说:

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函数。有没有办法做到这一点,还是我需要开始返回对象的副本?

6 个答案:

答案 0 :(得分:11)

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));




如果你想知道这是否是一个好主意,答案是否定的。构造一个新对象,从函数返回并分配 - 这是一种非常优选的方式。

答案 1 :(得分:1)

如果你包装你的对象并改变像这样的修改函数,你可以实现这个(不完全是你想要的),

var wrapper = {};
wrapper.x = {a:1};
function modify(obj, key) {
    obj[key] = {b:2};
}
modify(wrapper, 'x');
console.log(wrapper.x); // {b:2}

答案 2 :(得分:0)

我遇到了这个问题。经过一些研究,我选择将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.

谢谢,

答案 3 :(得分:0)

/**
 * 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];
    }
  });
}

答案 4 :(得分:-1)

'

答案 5 :(得分:-2)

为什么修改不会编辑obj引用的对象?

因为在写下时修改

obj = {b:2}

请注意, obj 修改的函数调用的局部变量。创建了一个新对象{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 的值现在已设置。

相关问题