【问题标题】:What does { ...obj1, obj2 } do exactly [duplicate]{ ...obj1, obj2 } 到底做了什么[重复]
【发布时间】:2019-09-05 04:54:45
【问题描述】:

假设我们有两个对象:

const state = {
  fishes: { /* some obj data */ },
  animals: { /* some obj data  */ }

const animals = { /* some NEW data */ }

在 Vuex 中有一个方法 replaceState(),根据 documentation,它接受一个参数并用该对象替换状态。

以下结果会是什么:

replaceState({ ...state, animals })

更具体地说,{ ...state, animals } 究竟做了什么?

为了提供一些背景信息,我从this 问题的答案中举了这个例子。在那个问题中,用户想要将状态的animals 属性替换为新对象animals

我不确定这是否与 Vuex / Vue.js 相关,还是纯粹的 JS 问题,但无论如何我都会用 vue.js 标记它。

【问题讨论】:

标签: javascript vue.js ecmascript-6 vuex ecmascript-2018


【解决方案1】:

这实际上来自 ECMAScript 2018 的 spread syntax 和 ECMAScript 2015 的 object destructuring

{ ...state, animals } 创建state 对象的浅表副本,并带有一个名为animals 的新属性(其中包含动物对象的值)。

由于您是 Vuex 用户,这符合immutable update patterns 的规则,即防止“原始”状态对象被更改或变异。您应该阅读使用不可变模式处理常见操作(例如添加/更新/删除)的方法。

【讨论】:

  • 仅供参考,数组传播与对象传播不同。对象扩展是 ES7 的一部分,而数组扩展是 ES6 的一部分
  • @Rajesh 感谢您指出这一点!它确实有时会让人感到困惑,因为在提案之后传播适用于对象和数组。
  • “带有一个名为 animals 的新属性” - 但是如果状态对象已经包含一个属性 animal,它会被覆盖吗?另外,在我的示例中,解构不会导致将多个参数传递给 replaceState() 函数吗?
  • @NikolayDyankov 是的,我相信确实如此。事实上,它从“原始”状态对象创建了一个浅拷贝。您可以尝试通过对复制的对象进行变异来测试它并在它们两个上运行 console.log() 以查看差异!
  • 但是,我必须提醒您注意,如果animals 是一个嵌套对象,您将不得不浅拷贝它的各个级别。这个链接有一个很好的例子redux.js.org/recipes/structuring-reducers/…。我希望我不会对所有这些 URL 感到厌烦,但理解这个重要概念对您来说至关重要。
【解决方案2】:

意思是Object.assign({}, state, { animals: animals} }

【讨论】:

  • 这更像是一条评论。如果您添加有关正在发生的事情,其目的是什么等的解释,这将对读者有所帮助
  • 据我所知 Object.assign() 对两个对象进行了浅合并,但为什么要解构第二个对象?
  • 实际上,我不是在解构第二个,而是使用旧的、冗长的 ES5 对象表示法。
  • 哦对了。我开始看到到处都在解构,哈哈
【解决方案3】:

它的作用是将state 的所有属性传播到新对象中——制作一个浅拷贝。原始对象 (state) 中的所有属性都将复制到新对象中(您传递给 replaceState 的对象)。这是一个简单的演示:

let obj1 = { obj: "1" };
let obj2 = { ...obj1, obj2: true };
console.log(obj1);
console.log(obj2);

animals 位是ES6 property shorthand,基本上会这样做:

animals: animals

这只是更简洁的语法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    • 2010-10-18
    • 2022-11-10
    • 2016-01-19
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多