【问题标题】:JavaScript: Reverse object destructuring / refactoring code to update object [duplicate]JavaScript:反向对象解构/重构代码以更新对象[重复]
【发布时间】:2018-09-04 15:52:06
【问题描述】:

TLDR:如何使用解构来加速基于同一接口的另一个对象的一个​​对象的部分更新?

我想使用新的 ECMA2015 - 2017 JavaScript 来重构我的代码。

为简单起见,假设我有一个对象,如下所示:

export interface myObj {
  name:           string;
  id:             number;
  description:    string;
  someBool:       boolean;
  anotherBool:    boolean;
}

(导出接口有效,因为我正在使用 Typescript 在 Angular 中工作)。

这里是旧的 es5 函数:

updateMyObj = function(oldObj, newObj) {
  var someBoolSaved = oldObj.someBool;
  var anotherBoolSaved = oldObj.anotherBool;
  oldObj = newObj;
  oldObj.someBool = someBoolSaved;
  oldObj.anotherBool = anotherBoolSaved;
}

如您所见,该函数应该更新 oldObj 的某些部分,但也要保留一些部分。

这是我重构代码的尝试:

updateObj(oldObj, newObj) {
  let {someBool, anotherBool} = oldObj;
  oldObj = newObj;
  // Here is the part where I don't know how to proceed.
}

但我不知道,我现在如何将 oldObj 的布尔值分配给保存的布尔值。

一种不优雅的方式是

oldObj.someBool = someBool;
oldObj.anotherBool = anotherBool;

在这个例子中会很好。但在我的实际任务中,这会花费很多代码行,这就是我要重构的原因。

我只是想不出正确的语法。

我编写此代码的尝试如下所示:

oldObj = {someBool, anotherBool}

但这不起作用。

【问题讨论】:

  • export interface ...?即使是 ES2018 草案也没有 interface 意味着什么,它仍然是一个“未来的保留词”。
  • 那是因为我猜我正在使用 Angular 和 Typescript。我在问题中编辑了它:)
  • "oldObj = newObj;" - 抱歉什么?我认为您应该首先开始将您的 ES5 代码简化为 function updateMyObj(oldObj, newObj) { newObj.someBool = oldObj.someBool; newObj.anotherBool = oldObj.anotherBool; }
  • 谢谢@Bergi。那甚至更短。不过,你会如何在 ES6+ 中编写它?
  • @J.Hesters 实际上并没有什么不同。这非常简单明了。副本中和 T.J.Crowder 提到的技术并没有太大的收获。

标签: javascript ecmascript-6 refactoring destructuring object-destructuring


【解决方案1】:

const newObj = { ...oldObject, someBool: true, anotherBool: false};

编辑:

更新旧对象真的是你想要做的吗?

在您的原始代码中,您改变 oldObj 作为函数的副作用。这通常被视为不良做法。下面是一个没有副作用的纯函数示例。

const firstObj = { name: 'hi', someBool: true, anotherBool: true };
const secondObj = { name: 'bye', someBool: false }; 
const thirdObj = mergeObjects(firstObj, secondObj);
// work with thirdObj from now on

function mergeObjects(firstObj, secondObj): myObj {
  return { 
    ...secondObj,
    firstObj.someBool,
    firstObj.anotherBool 
  }
}

【讨论】:

  • 问题预设了要更新的现有对象。上面创建了一个 new 对象。 (另外:代码转储不是有用的答案。)
  • 那是 ES2018。 OP 要求 ES2015-ES2017 的解决方案 :-)
  • @Bergi:哈哈!确实如此,但我敢打赌他们愿意更进一步......
  • 硬编码的truefalse 如何帮助回答问题?
  • 是的,我愿意走得更远,谢谢! :)
【解决方案2】:

如果要将解构后的值分配给属性,可以通过在解构中指定 : 右侧的属性来实现。

例如:以下将newObj.anewObj.c 分配给oldObj.aoldObj.c

({a: oldObj.a, c: oldObj.c} = newObj);
//   ^^^^^^^^-----^^^^^^^^---- destinations for a and c

() 是必需的,否则开头的 { 看起来像块的开头。如果我们已经在表达式上下文中,则不需要它们。)

const oldObj = {a: "old a", b: "old b"};
const newObj = {a: "new a", c: "new c"};
({a: oldObj.a, c: oldObj.c} = newObj);
console.log(oldObj);

正如 Bergi 在对该问题的评论中指出的那样,它并没有真正让你买太多

oldObj.a = newObj.a;
oldObj.c = newObj.c;

这是各种pick notations 出现的原因之一(最近才看到活动)。如果该提议被接受(而且它甚至还没有冠军,所以不要屏住呼吸),你会有oldObj.{a, c} = newObj;

【讨论】:

  • 当然,如果这是在编译单元的开头,则可能想要;,以避免在组合时将其误认为是函数参数在其他代码之后... :-)
  • 谢谢 T.J. :) 这些选择符号看起来不错,我希望它们能被接受。而且我仍然会寻求您的答案,因为在我的现实生活用例中,确实需要处理的不仅仅是两行:)
  • (我应该知道这已经被回答了。我的错。)
猜你喜欢
  • 2020-04-11
  • 2019-04-27
  • 2016-05-17
  • 2018-04-12
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-17
相关资源
最近更新 更多