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

c-c*_*vez 3 javascript

我已经看过这篇文章,并想知道是否有一种方法可以使用javascript编写一个函数,可以通过使用具有新值的另一个对象来有条件地更新对象的所有属性?

说我有这个对象:

let oldObj = {test1: 'valueTest1',test2: 'valueTest2',test3: 'valueTest3' };
Run Code Online (Sandbox Code Playgroud)

我想使用另一个对象传递的属性更新其值,如下所示:

let newObj = {test2: 'newValue2'}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我只想更新属性"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},
};
Run Code Online (Sandbox Code Playgroud)

意思是我只会在属性进入新对象时更新值,但当然我必须添加与对象中的属性一样多的条件.

这种方法很好,但它没有推广,所以如果对象有10个属性,我将不得不写出10个条件.

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

T.J*_*der 7

你在评论中说过:

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

这意味着我们必须保持扩展语法和Object.assign图片,因为它们都会将所有属性从newObjover 复制到oldObj.

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

for (const key of Object.keys(newObj)) {
  if (key in oldObj) {
    oldObj[key] = newObj[key];
  }
}
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

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

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

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

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);
Run Code Online (Sandbox Code Playgroud)


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

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

oldObj = {...oldObj, ...newObj};
Run Code Online (Sandbox Code Playgroud)

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

oldObj = {...oldObj, ...newObj};
console.log(oldObj);
Run Code Online (Sandbox Code Playgroud)

这将创建一个具有所有oldObj's'和newObj's属性的新对象,newObj如果两者具有相同的名称,则其属性将获胜.

请注意,物业价差是全新的,只是批准到第4阶段(将在ES2018规范中).如果您不想使用第4阶段提案,请使用Object.assign:

oldObj = Object.assign({}, oldObj, newObj);
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

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

Object.assign(oldObj, newObj);
Run Code Online (Sandbox Code Playgroud)

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

Object.assign(oldObj, newObj);
console.log(oldObj);
Run Code Online (Sandbox Code Playgroud)


  • @ c-chavez:是的.当我看到你的评论时,我重新安排了答案,将那些没有做到这一点的版本放在首位(并重命名变量). (2认同)