为什么要使用扩展运算符将变量扩展到自身?

Why would you use the spread operator to spread a variable onto itself?

在 Google Getting started with Node.js 教程中,他们执行以下操作

data = {...data};

在向 Firestore 发送数据的代码中。

您可以在第 63 行 their Github 上看到它。

据我所知这没有任何作用。

这样做有充分的理由吗?

它是否有可能在未来进行验证,因此如果您添加自己的数据,您就不太可能做类似 data = {data, moreData} 的事情?

正在制作 shallow copydata;假设您有一个第三方函数可以改变输入:

const foo = input => {
  input['changed'] = true;
}

并且您需要调用它,但又不想修改您的对象,所以不是:

data = {life: 42}
foo(data)

// > data
// { life: 42, changed: true }

您可以使用 Spread Syntax:

data = {life: 42}
foo({...data})

// > data
// { life: 42 }

不确定这是否是 Firestone 的特殊情况,但事实是:传播一个对象你会得到该对象的浅表副本。

===

相关:

@Manu 的回答细节 什么 这行代码在做什么,但不是 为什么 它在那里。

我不知道为什么 Google 代码示例使用这种方法,但我猜测原因如下(在这种情况下我自己也会这样做):

因为 JavaScript 中的对象是通过引用传递的,因此有必要从其组成部分重建 'data' 对象,以避免原始数据对象被 ref.set 进一步修改(数据)在示例代码的第 64 行调用:

await ref.set(data);

例如,在 MongoDB 中,当您将对象传递给写入或更新方法时,Mongo 实际上会修改对象以添加额外的属性,例如插入到的日期时间集合或其在集合中的 ID。我不确定 Firestore 是否会做同样的事情,但如果现在没有,将来可能会。如果是这样,并且如果您从 Google 的示例代码调用更新方法的原始代码继续进一步操作它最初传递的数据对象,那么该对象现在将具有额外的属性,这可能会导致意外问题。因此,谨慎的做法是根据原始对象的属性重建数据对象,以避免在代码的其他地方污染原始对象。

我希望这是有道理的 - 我越想越相信这一定是原因,这实际上是一个很好的学习点。


我在这里包含了 Google 代码中的完整原始函数,以防将来其他人遇到这个问题,因为代码可能会更改(在撰写本文时从 https://github.com/GoogleCloudPlatform/nodejs-getting-started/blob/master/bookshelf/books/firestore.js 复制这个答案):

// Creates a new book or updates an existing book with new data.
async function update(id, data) {
  let ref;
  if (id === null) {
    ref = db.collection(collection).doc();
  } else {
    ref = db.collection(collection).doc(id);
  }

  data.id = ref.id;
  data = {...data};
  await ref.set(data);
  return data;
}