javascript有条件地更新内部部分属性,而不删除其他属性

时间:2018-08-29 20:04:03

标签: javascript

我之前问过this question,但是现在我面临着另一个问题。

我有这些对象:

let oldObj = { 
    test1: 'valueTest1',
    test2: {
        inner1: 'valueInner1',
        inner2: 'valueInner2',
        inner3: {
            otherInner1: 'valueOtherInner1',          
            otherInner2: 'valueOtherInner2'
            }
        },
    test3: 'valueTest3' 
};

let newObj = {
    test2: {
        inner1: 'newValueInner1',
        }
}

并使用以下代码:

for (const key of Object.keys(newObj)) {
  if (key in oldObj) {
    oldObj[key] = newObj[key];
  }
}

我得到:

{
    test1:'valueTest1',
    test2: {
        inner1: 'newValueInner1'
        },
    test3:'valueTest3'
}

但是我不想删除内部对象的其他属性(inner2,inner3等)。我希望得到这样的结果:

{ 
    test1: 'valueTest1',
    test2: {
        inner1: 'newValueInner1',
        inner2: 'valueInner2',
        inner3: {
            otherInner1: 'valueOtherInner1',          
            otherInner2: 'valueOtherInner2'
            }
        },
    test3: 'valueTest3' 
}

有没有一种功能可以做到这一点?

这里的对象只是示例,我要实现的是创建一个可以深度修改对象属性而不删除其余部分的函数。

例如,如果我将newObj定义为:

let newObj = {
    test2: {
        inner3: {
            otherInner1:'newValueInner1'
            }
        }
}

我应该得到:

{ 
    test1: 'valueTest1',
    test2: {
        inner1: 'valueInner1',
        inner2: 'valueInner2',
        inner3: {
            otherInner1: 'newValueInner1',          
            otherInner2: 'valueOtherInner2'
            }
        },
    test3: 'valueTest3' 
};

3 个答案:

答案 0 :(得分:1)

如果可以使用解构,则可以将值从newObj解构到oldObj

let oldObj = { 
    test1: 'valueTest1',
    test2: {
        inner1: 'valueInner1',
        inner2: 'valueInner2',
        inner3: {
            otherInner1: 'valueOtherInner1',          
            otherInner2: 'valueOtherInner2'
            }
        },
    test3: 'valueTest3' 
};

let newObj = {
    test2: {
        inner1: 'newValueInner1',
    }
}

for (const key of Object.keys(newObj)) {
  if (key in oldObj) {
    oldObj[key] = {
      ...oldObj[key], // set oldObj[key] to itself
      ...newObj[key]  // override properties from newObj[key]
    }
  }
}

console.log(oldObj)

编辑:正如@riv指出的那样,您也可以使用Object.assign

oldObj[key] = Object.assign(oldObj[key], newObj[key]);

答案 1 :(得分:1)

您需要迭代对象条目,如果找到了另一个对象,请使用嵌套的对象进行更新。

function update(target, source) {
    Object.entries(source).forEach(([key, value]) => {
        if (value && typeof value === 'object') {
            update(target[key] = target[key] || {}, value);
            return;
        }
        target[key] = value;
    });
}

var oldObj = { test1: 'valueTest1', test2: { inner1: 'valueInner1', inner2: 'valueInner2', inner3: { otherInner1: 'valueOtherInner1', otherInner2: 'valueOtherInner2' } }, test3: 'valueTest3' },
    newObj = { test2: { inner1: '!!!!!!!!!!!!' } };

update(oldObj, newObj);
console.log(oldObj);

答案 2 :(得分:0)

该函数正在执行的操作是遍历第一层I.E. test1,test2,test3。然后,它将使用新对象,而不是插入新值,而是替换新值。您需要做的是将一个循环放入内部对象内部,然后更新值。像这样:

for (var item in newObj)
{
  // is item an value item?
  if(typeof newObj[item] == "string")
  {
     oldObj[item] = newObj[item];
  }
  // Is the value an object with inner items?
  else if(typeof newObj[item] == "object")
  {
    for(var innerItem in newObj[item])
    {
      if(typeof newObj[item][innerItem] == "string")
      {
         oldObj[item][innerItem] = newObj[item][innerItem];
      }
    }
  }
}