Javascript 使用immutable.js优于Object.assign或spread运算符的优点

Javascript 使用immutable.js优于Object.assign或spread运算符的优点,javascript,reactjs,redux,immutability,Javascript,Reactjs,Redux,Immutability,到目前为止,我看到的大多数“初学者样板”和一些关于react/redux的帖子都鼓励使用来解决可变性问题。我个人依赖于Object.assign或spread操作符来处理这个问题,因此没有看到immutable.js的优势,因为它增加了额外的学习,并稍微改变了用于可变性的普通js技术。我试图找到切换的有效原因,但未能找到,因此我在这里询问它为什么如此流行。提供了许多始终返回新对象的实用程序 例如: var Immutable = require('immutable'); var map1 =

到目前为止,我看到的大多数“初学者样板”和一些关于react/redux的帖子都鼓励使用来解决可变性问题。我个人依赖于
Object.assign
或spread操作符来处理这个问题,因此没有看到immutable.js的优势,因为它增加了额外的学习,并稍微改变了用于可变性的普通js技术。我试图找到切换的有效原因,但未能找到,因此我在这里询问它为什么如此流行。

提供了许多始终返回新对象的实用程序

例如:

var Immutable = require('immutable');
var map1 = Immutable.Map({a:1, b:2, c:3});
var map2 = map1.set('b', 50);
map1.get('b'); // 2
map2.get('b'); // 50

对于just react/redux,我个人认为Object.assign足够强大,但在某些情况下,使用该库可以为您节省几行代码。

immutable.js的优点是它强制执行一个不可变的redux存储(您可能会忘记扩展,或者在保护您的存储免受修改方面做得很草率)和
对象相比,简化了缩减器。分配
或扩展运算符(顺便说一句,两者都很肤浅!)


话虽如此,我在Angular 1.x大型项目中使用了redux+immutable,但也有缺点:性能问题,不清楚什么是不可变的,什么是不可变的,Angular不能在
ng repeat
中使用immutable.js结构,等等。虽然不确定React,但我很乐意听取意见。

我认为ImmutableJs的主要优点是当然,它也加强了不变性,但无论如何你都应该这样做,所以这只是一个额外的好处

例如,假设您的reducer中有一个非常大的对象,并且您希望更改该对象的一小部分。由于不变性,您不能直接更改该对象,但必须创建该对象的副本。您可以通过复制所有内容(在ES6中使用扩展运算符)来完成此操作

那么问题出在哪里呢?复制非常大的对象非常慢。ImmutableJS中的数据结构执行一种称为结构共享的操作,您实际上只更改所需的数据。未更改的其他数据在对象之间共享,因此不会被复制

其结果是高效的数据结构,具有快速写入

ImmutableJS还为深度对象提供了简单的比较

const a = Immutable.Map({ a: Immutable.Map({ a: 'a', b: 'b'}), b: 'b'});
const b = Immutable.Map({ a: Immutable.Map({ a: 'a', b: 'b'}), b: 'b'});

console.log(a.equals(b)) // true 
如果没有这一点,您将需要某种深度比较函数,这也需要很多时间,而这里的根节点包含整个数据结构的散列(请不要引用我的话,这是我的记忆,但比较总是即时的),因此比较总是
O(1)
即即时,与对象大小无关

这在React
shouldComponentUpdate
方法中特别有用,在该方法中,您可以使用此
equals
函数比较道具,该函数可即时运行

当然,也有缺点,如果混合使用immutablejs结构和常规对象,可能很难分辨什么是什么。此外,您的代码库中充斥着immutablejs语法,这与常规Javascript不同

另一个缺点是,如果您不打算使用深度嵌套的对象,它将比普通的旧js慢一点,因为数据结构确实有一些开销


只要我的2美分。

这都是关于效率的

持久数据结构 持久性数据结构在发生变异时始终会产生新的数据结构,从而保留其自身的以前版本。为了避免昂贵的克隆,只存储与以前数据结构的差异,而在它们之间共享交叉点。这种策略称为结构共享。因此,持久性数据结构非常有用比使用
对象进行克隆更有效。分配
或扩展运算符

Javascript中持久数据结构的缺点 不幸的是,Javascript本机不支持持久数据结构。这就是immutable.js存在的原因,它的对象与普通的旧Javascript
Object
s有很大的不同。这会导致更详细的代码和大量持久数据结构到本机Javascript数据结构的转换

关键问题 什么时候immutable.js的结构共享(效率)的好处超过了它的缺点(冗长、转换)


我猜只有在大型项目中,当整个数据结构的克隆和垃圾收集变得更加昂贵时,库才能获得回报。

我已经为多个不可变库创建了性能基准,脚本和结果位于中,这表明这是优化对于写入操作,它的速度比Object.assign()快,但是对于读取操作,它的速度较慢。以下是基准测试结果的摘要:

-- Mutable
Total elapsed = 50 ms (read) + 53 ms (write) = 103 ms.

-- Immutable (Object.assign)
Total elapsed = 50 ms (read) + 2149 ms (write) = 2199 ms.

-- Immutable (immutable.js)
Total elapsed = 638 ms (read) + 1052 ms (write) = 1690 ms.

-- Immutable (seamless-immutable)
Total elapsed = 31 ms (read) + 91302 ms (write) = 91333 ms.

-- Immutable (immutable-assign (created by me))
Total elapsed = 50 ms (read) + 2173 ms (write) = 2223 ms.
因此,是否使用immutable.js将取决于应用程序的类型及其读写比。如果您有很多写操作,那么immutable.js将是一个不错的选择


理想情况下,在引入任何性能优化之前,您应该对应用程序进行概要分析,但是,不变性是必须尽早决定的设计决策之一。当您开始使用时,您需要在整个应用程序中使用它以获得性能优势,因为使用fromJS()和toJS()与普通JS对象进行互操作非常昂贵。

这不仅仅是通过持久性数据结构提高性能。不变性本身就是非常理想的质量,因为它完全消除了由意外突变引起的任何错误。此外,在Javascript中有健全的数据结构和方便的API是很好的,一些实际可用的东西,而immutable.js就是最好的选择领先于vanillla对象和数组,即使最近添加了ES6和ES7。它就像jQuery一样——它非常流行,因为它的API非常棒,而且易于使用