如果我有一个现有的对象,数组或地图,并且想要删除或添加项,则首先复制(浅复制)地图,然后在新地图上使用delete方法,这被认为是正确的方法。保持不变?
编辑
在我学过的功能语言(如Elixir)中,诸如List之类的数据结构会返回一个新的List。 JS不能这样工作。甚至像reduce这样的数组方法仍然将空数组作为初始参数,并推送项目 (将初始数组变异)到其中。
const map = new Map([
['dog', 'Dog'],
['cat', 'Cat'],
['chicken', 'Chicken'],
])
const map2 = new Map([
...map,
])
map2.delete('dog')
答案 0 :(得分:1)
您正在突变map2
。但是,在合理的封装逻辑上(例如将clone + delete放入函数中),它仍然被视为纯操作,并且您作为参数传递的原始对象将保持不变。
功能
function withoutDog(map) {
const map2 = new Map(map);
map2.delete('dog');
return map2;
}
function withoutDog(map) {
return new Map(Array.from(map).filter(([key, _]) => key !== 'dog'));
}
与外面没有区别。
答案 1 :(得分:0)
当某些东西是不可变的时,仅表示它不会改变状态。
由于您没有更改对象的状态(即object.foo ='bar'),而是要克隆它并对其进行突变,所以它是不可变的。
答案 2 :(得分:0)
不,这不是不变性的例子。
如果无法修改其内容,则该对象是不可变的。制作对象的副本使您可以修改副本而无需修改原始对象,但是您仍然可以根据需要修改原始对象。
In [23]: %timeit searchsorted2d(a,b)
100 loops, best of 3: 7.26 ms per loop
答案 3 :(得分:0)
OP是否在询问数据结构是不可变的,还是这里使用的模式是否不变?这个问题本质上是令人困惑的,因为我们通常将不可变用作数据结构的形容词,而不是算法的实现。我们通常将设计用于不可变数据结构的算法实现描述为“纯函数”或“纯运算”。
根据“不可变”的通常定义,@ Barmar的正确答案是问题中的数据结构不是不可变的,因为JS中的对象是可变的。即使我们使用const声明,const关键字也只是使对对象的引用不可变,但是对象内的值仍然可以改变。我们现在持有对可变的复合值的不可变原子引用。
但是OP的措辞(“正在克隆……被认为是不可变的”)表明,问题的实质是询问所讨论的过程是否是不可变的。因此,@ Bergi的答案是通过将“不可变的”解析为“纯净的”来很好地回答问题。如果将此逻辑封装在API中,则即使实现在内部不是纯净的,该API也会为调用者提供纯操作/函数,因为它会在返回本地值之前对其进行修改。