小编典典

为什么要在object.freeze上使用immutablejs?

reactjs

我在网上研究过immutablejs的好处,Object.freeze()但是没有发现任何令人满意的东西!

我的问题是,当我可以冻结一个普通的旧javascript对象时,为什么我应该使用该库并使用非本机数据结构?


阅读 245

收藏
2020-07-22

共1个答案

小编典典

我认为您不了解immutablejs提供的功能。这不是一个使您的对象变得不可变的库,而是一个使用不可变值的库。

在不简单重复他们的文档任务说明的情况下,我将说明它提供的两件事:

  1. 类型。他们实现了(不可变的)无限范围,堆栈,有序集,列表等。

  2. 它们的所有类型都实现为持久数据结构

我撒谎了,以下是他们的使命宣言:

不变的数据一旦创建就无法更改,从而可以简化应用程序开发,进行防御性复制,并可以使用简单的逻辑实现高级的备忘和更改检测技术。持久数据提供了一个可变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一个对象就足够了。哎呀,多数认为是时候
绰绰有余。这是一个有用的库,有它的利基市场,只是不要被炒作所迷惑。

2020-07-22