在Javascript中,如何有条件地更新对象的属性?

时间:2018-02-12 14:43:20

标签: javascript

我见过this post并且想知道是否有一种方法可以使用javascript来编写一个函数,该函数可以通过使用具有新值的另一个对象来有条件地更新对象的所有属性?

说我有这个对象:

let oldObj = {test1: 'valueTest1',test2: 'valueTest2',test3: 'valueTest3' };

我想使用另一个对象传递的属性来更新它的值:

let newObj = {test2: 'newValue2'}

在这种情况下,我只想更新属性“test2”。如果我知道我想要更新的属性并且我事先知道原始属性,我将使用:

oldObj = {
  ...(newObj.test1) && {test1: newObj.test1} || {test1: oldObj.test1},
  ...(newObj.test2) && {test2: newObj.test2} || {test2: oldObj.test2},
  ...(newObj.test3) && {test3: newObj.test3} || {test3: oldObj.test3},
};

含义如果属性出现在新对象中,我只会更新值,但当然我必须添加与对象中的属性一样多的条件。

这种方法很好,但它没有概括,所以如果对象有10个属性,我就要编写10个条件。

有没有办法编写一个可以有条件地更新属性的函数,这样我就不必编写10个(或更多)条件?

1 个答案:

答案 0 :(得分:7)

你在评论中说过:

  

我只会更新旧对象中存在的属性,不会添加旧对象中不存在的新属性。

这意味着我们必须将展开语法和Object.assign保留在图片之外,因为它们都会将所有属性从newObj复制到oldObj

相反,我们可以使用一个简单的循环(如果这出现了很多,你可以创建一个函数,也许是updateObject):

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

let oldObj = {test1: 'valueTest1',test2: 'valueTest2',test3: 'valueTest3' };
let newObj = {test2: 'newValue2', xyz: "don't copy me"};

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

(根据您的更新规则,您可能更喜欢oldObj.hasOwnProperty(key)而不是key in oldObj。)

或使用相对较新的Object.entries和一些解构:

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

let oldObj = {test1: 'valueTest1',test2: 'valueTest2',test3: 'valueTest3' };
let newObj = {test2: 'newValue2', xyz: "don't copy me"};

for (const [key, value] of Object.entries(newObj)) {
  if (key in oldObj) {
    oldObj[key] = value;
  }
}
console.log(oldObj);

在上面提到的澄清之前,我发布了以下有​​关传播和Object.assign的内容。仅为了完整性,但它们不适用于您要跳过oldObj没有的属性的情况:

您不必像传播语法一样复杂,只需:

oldObj = {...oldObj, ...newObj};

let oldObj = {test1: 'valueTest1',test2: 'valueTest2',test3: 'valueTest3' };
let newObj = {test2: 'newValue2', xyz: "I get copied too"};

oldObj = {...oldObj, ...newObj};
console.log(oldObj);

这将创建一个包含所有oldObjnewObj属性的新对象,如果两者具有相同的名称,则newObj的属性将获胜。

请注意,属性差价为全新,刚刚获得第4阶段批准(将在ES2018规范中)。如果您不想使用第4阶段提案,请使用Object.assign

oldObj = Object.assign({}, oldObj, newObj);

let oldObj = {test1: 'valueTest1',test2: 'valueTest2',test3: 'valueTest3' };
let newObj = {test2: 'newValue2', xyz: "I get copied too"};

oldObj = Object.assign({}, oldObj, newObj);
console.log(oldObj);

如果您想在原地更新Object.assign而不是创建新对象,也可以使用oldObj

Object.assign(oldObj, newObj);

let oldObj = {test1: 'valueTest1',test2: 'valueTest2',test3: 'valueTest3' };
let newObj = {test2: 'newValue2', xyz: "I get copied too"};

Object.assign(oldObj, newObj);
console.log(oldObj);