为什么要使用JavaScript spread操作符来更新数组中的项?

为什么要使用JavaScript spread操作符来更新数组中的项?,javascript,reactjs,Javascript,Reactjs,我正在学习一门在线课程,我很想知道为什么导师会使用扩展操作符来更新数组中的对象,而不仅仅是使用对象本身 我在谷歌上搜索了一下,找到了关于spread operator的信息,但不知道他为什么这么做 例如: handleUpdate = async (post) => { post.title = "Updated"; ... const posts = [...this.state.posts]; const index = posts.indexOf(post);

我正在学习一门在线课程,我很想知道为什么导师会使用扩展操作符来更新数组中的对象,而不仅仅是使用对象本身

我在谷歌上搜索了一下,找到了关于spread operator的信息,但不知道他为什么这么做

例如:

handleUpdate = async (post) => {
   post.title = "Updated";
   ...
   const posts = [...this.state.posts];
   const index = posts.indexOf(post);

   // why use this
   posts[index] = { ...post };

   // instead of 
   // posts[index] = post;

   this.setState({ posts });
})

我已经用直接设置的对象进行了测试,它似乎有效,但我很感兴趣的是,为什么您会使用一种方法而不是另一种?这只是一种偏好,还是更多


谢谢。

我能看到的主要原因是创建对象的浅层副本,这样,如果对副本执行任何操作,它都不会改变原始副本。这在函数式编程范例中尤其有用,因为您不想改变任何共享对象/维护共享状态

但是,正如我所提到的,这只会创建一个浅拷贝(与深拷贝相反),因此,如果对象的任何属性本身是可变的(例如数组属性),那么这些属性仍然可以进行变异

编辑:根据评论中的问题以及@AdiH在回答中提到的内容,在创建浅层副本之前更新
post.title
似乎没有任何意义,因为这会改变原始对象。作者可能希望这一变更同时反映在原件和复印件中,但任何进一步的变更仅反映在复印件中

const x={a:b',c:d',d:[]};
const copy={…x};
copy.a='c';
console.log(x);//不变的
常数相同=x;
相同。a='c';
console.log(x);//改变
复制。d.推送(“e”);

console.log(x);//x、 d已更改
原因与不变性模式有关。没有任何变化,而是创建一个新对象并更改该对象。它使变化检测变得简单


然而,如果开发人员很小心,这并不总是必要的

我能看出你的困惑。我认为这个例子并不好。人们只能猜测作者的想法,但如果他或她打算强制执行不变性,我就不会这样做,因为它显然会发生变异

相反,我会这么做的
post[index]={…post,标题:“Updated”}
请参阅


是的,我也猜不出这个例子背后的动机。

,语法也很优雅。例如:
x=[1,2,3];y=[…x];z=x;y[1]=0;z[1]=5;log(x==y,x==z,x,y,z)
Ah。。。我懂了。谢谢你的澄清。现在有道理了。但有一件事,在我发布的示例中,他修改了传递给方法的对象,而不是像您那样立即创建对象的副本,然后使用对象的“浅”副本来更新数组。这是否意味着如果“post”处于共享状态,它将被更新?@Thierry没问题,是的,在这种情况下,原始对象
post
将被更新,并且该更改将反映在浅层副本中。我不确定作者想证明原始对象也被更新的背后是否有特定的理由,Edit@AdiH只是在他们的回答中提到了这一点,我同意,在那个特定的用例中似乎没有任何意义