繁体   English   中英

例如,克隆对象、映射或数组然后使用删除是否被认为是不可变的?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM