[英]Is cloning an object, map or array and then using delete for example, considered immutable?
如果我有一个现有的对象、数组或地图,并且我想删除或添加和项目,是否首先复制(浅拷贝)地图,然后在新地图上使用删除方法,被认为是保持不变性的正确方法?
编辑
在像 Elixir 这样的函数式语言中,像 List 这样的数据结构会返回一个新的 List。 JS 不是这样工作的。 即使是像 reduce 这样的数组方法,仍然将一个空数组作为初始参数,并将项目(改变初始数组)推入其中。
const map = new Map([
['dog', 'Dog'],
['cat', 'Cat'],
['chicken', 'Chicken'],
])
const map2 = new Map([
...map,
])
map2.delete('dog')
你正在改变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'));
}
与外界无法区分。
当某些东西是不可变的时,它仅仅意味着它不会改变状态。
由于您不是在更改对象的状态(即 object.foo = 'bar'),而是在克隆它并对克隆进行变异,因此它是不可变的。
不,这不是不变性的一个例子。
如果无法修改其内容,则对象是不可变的。 制作对象的副本允许您在不修改原始对象的情况下修改副本,但如果需要,您仍然可以修改原始对象。
const map = new Map([
['dog', 'Dog'],
['cat', 'Cat'],
['chicken', 'Chicken'],
])
const map2 = new Map(map) // clone the Map
map2.delete('dog') // modify the clone -- doesn't affect the original
map.delete('cat') // modify the original -- it's not immutable
OP 是否询问数据结构是否不可变,或者此处使用的模式是否不可变? 这个问题本质上令人困惑,因为我们通常使用 immutable 作为数据结构的形容词,而不是算法实现; 我们通常将设计用于不可变数据结构的算法实现描述为“纯函数”或“纯操作”。
根据“不可变”的通常定义,@Barmar 是正确的,答案是问题中的数据结构不是不可变的,因为 JS 中的对象是可变的。 即使我们使用 const 声明,const 关键字也只是使对对象的引用不可变,但对象内的值仍然可以改变; 我们现在持有对可变复合值的不可变原子引用。
但是 OP 的措辞(“是克隆......被认为是不可变的”)表明真正的问题是询问所讨论的过程是否是不可变的。 因此,@Bergi 的答案是通过将“不可变”解析为“纯”来回答问题的一个很好的尝试。 如果将此逻辑封装在 API 中,该 API 将向调用者提供纯操作/函数,即使实现在内部不是纯的,因为它会在返回之前修改本地值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.