如何在javascript中保持对象不可变的数组?

Pie*_*rre 8 javascript arrays mutability

我想基于两个数组创建一个数组 - “ideaList”和“endorsements”全局声明。由于ideaList 和endorsements 用于程序的其他部分,我需要它们是不可变的,我认为 .map 和 .filter 会保持这种不变性。

function prepareIdeaArray(){
var preFilteredIdeas=ideaList
        .filter(hasIdeaPassedControl)
        .map(obj => {obj.count = endorsements
                                 .filter(x=>x.ideaNumber===obj.ideaNumber)
                                 .reduce((sum, x)=>sum+x.count,0); 
                     obj.like = endorsements
                                 .filter(x=>x.ideaNumber===obj.ideaNumber && x.who===activeUser)
                                 .reduce((sum, x)=>sum+x.count,0)===0?false:true
                     obj.position = generatePosition(obj.status)
                     obj.description = obj.description.replace(/\n/g, '<br>')  
                     return obj;});
preFilteredIdeas.sort(compareOn.bind(null,'count',false)).sort(compareOn.bind(null,'position',true))
return preFilteredIdeas;
}
Run Code Online (Sandbox Code Playgroud)

但是,当我在这个函数执行完console.logideaList的时候,注意到数组的对象都有“count”、“like”、“position”属性和值,证明这个数组已经发生了变异。

我尝试仅使用 .map,但结果相同。

你知道我如何防止ideaList发生变异吗?另外我想避免使用const,因为我首先全局声明ideaList,然后在另一个函数中为其分配一些数据。

Len*_*olm 6

你不是在改变数组本身,而是改变数组包含引用的对象。.map()创建数组的副本,但其中包含的引用指向与原始对象完全相同的对象,您已通过直接向它们添加属性而对其进行了变异。

您还需要制作这些对象的副本并将属性添加到这些副本中。一个巧妙的方法是在.map()回调中使用对象传播:

    .map(({ ...obj }) => {
      obj.count = endorsements
                             .filter(x=>x.ideaNumber===obj.ideaNumber)
      ...
Run Code Online (Sandbox Code Playgroud)

如果您的环境不支持对象传播语法,请使用以下命令克隆对象Object.assign()

    .map(originalObj => {
      const obj = Object.assign({}, originalObj);
      obj.count = endorsements
                             .filter(x=>x.ideaNumber===obj.ideaNumber)
      ...
Run Code Online (Sandbox Code Playgroud)