我在网上研究过immutablejs的好处,Object.freeze()但是没有发现任何令人满意的东西!
Object.freeze()
我的问题是,当我可以冻结一个普通的旧javascript对象时,为什么我应该使用该库并使用非本机数据结构?
我认为您不了解immutablejs提供的功能。这不是一个使您的对象变得不可变的库,而是一个使用不可变值的库。
在不简单重复他们的文档和任务说明的情况下,我将说明它提供的两件事:
类型。他们实现了(不可变的)无限范围,堆栈,有序集,列表等。
它们的所有类型都实现为持久数据结构。
我撒谎了,以下是他们的使命宣言:
不变的数据一旦创建就无法更改,从而可以简化应用程序开发,进行防御性复制,并可以使用简单的逻辑实现高级的备忘和更改检测技术。持久数据提供了一个可变API,该API不会就地更新数据,而是始终产生新的更新数据。
我强烈建议你阅读它们链接到更多关于持久数据结构(因为他们的文章和视频 的 东西immutablejs约),但我会在一个句子或如此总结:
假设您正在编写游戏,并且有一个坐在2D平面上的玩家。例如,这里是鲍勃:
var player = { name: 'Bob', favouriteColor: 'moldy mustard', x: 4, y: 10 };
由于您喝了FP koolaid,所以您想冻结播放器(brrr!希望Bob穿一件毛衣):
var player = Object.freeze({ name: 'Bob', ... });
现在进入游戏循环。每次滴答声,玩家的位置都会改变。由于播放器对象已冻结,我们不能仅仅对其进行更新,因此我们将其复制到:
function movePlayer(player, newX, newY) { return Object.freeze(Object.assign({}, player, { x: newX, y: newY })); }
很好,很花哨,但是请注意我们正在进行多少无用的复制:在每个刻度上,我们创建一个新对象,遍历一个对象,然后在它们之上分配一些新值。在每个刻度上,在每个对象上。那真是满嘴。
不可变为您解决了这一问题:
var player = Immutable.Map({ name: 'Bob', ... }); function movePlayer(player, newX, newY) { return player.set('x', newX).set('y', newY); }
通过持久数据结构的“ *✧”魔术✧゚ ヽ,他们承诺将进行尽可能 少 的操作。
心态也有所不同。当使用“普通的旧的(冻结的)javascript对象”时,所有方面的默认操作 都是 假定可变性,并且您必须付出额外的努力才能实现有意义的可变性(也就是说,确认状态存在的可变性)。那是freeze存在的部分原因:当您尝试执行其他操作时,事情会慌乱。当然,使用Immutablejs时,不可变性是默认的假设,并且它上面还有一个不错的API。
freeze
并不是说所有的都是粉红色和玫瑰色,上面是樱桃。当然,所有事物都有其弊端,您不应该仅仅因为可以就在不可变的地方塞满东西。有时候,仅仅freeze一个对象就足够了。哎呀,多数认为是时候 更 绰绰有余。这是一个有用的库,有它的利基市场,只是不要被炒作所迷惑。