博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
为什么用Immutable.js代替普通js对象?
阅读量:6983 次
发布时间:2019-06-27

本文共 2588 字,大约阅读时间需要 8 分钟。

FROM URL:

将数据视为不可变,将给你带来很多好处。事实上,这是也React背后的原理:React的元素是不可变的。

但是用Immutable.js有什么好处呢?

假定有一个非常巨大的对象…

这里有100,000条待办事项:

var todos = {
t79444dae: { title: 'Task 50001', completed: false },
t7eaf70c3: { title: 'Task 50002', completed: false },
t2fd2ffa0: { title: 'Task 50003', completed: false },
t6321775c: { title: 'Task 50004', completed: false },
t2148bf88: { title: 'Task 50005', completed: false },
t9e37b9b6: { title: 'Task 50006', completed: false },
tb5b1b6ae: { title: 'Task 50007', completed: false },
tfe88b26d: { title: 'Task 50008', completed: false },
(100,000 items)
}我要把第50,005条任务的completed改为ture。

用普通的JavaScript对象

function toggleTodo (todos, id) {

return Object.assign({ }, todos, {
: Object.assign({ }, todos, {
completed: !todos.completed
})
})
}

var nextState = toggleTodo(todos, 't2148bf88')这项操作运行了134ms。

为什么用了这么长时间呢?因为当使用Object.assign,JavaScript会从旧对象(浅)复制每个属性到新的对象。
我们有100,000条待办事项,所以意味着有100,000个属性需要被(浅)复制。
这就是为什么花了这么长时间的原因。
在JavaScript中,对象默认是可变的。
当你复制一个对象时,JavaScript不得不复制每一个属性来保证这两个对象相互独立。
为什么用Immutable.js代替普通js对象?
100,000个属性被(浅)复制到新的对象。

使用Immutable.js

var todos = Immutable.fromJS({

t79444dae: { title: 'Task 50001', completed: false },
t7eaf70c3: { title: 'Task 50002', completed: false },
t2fd2ffa0: { title: 'Task 50003', completed: false },
t6321775c: { title: 'Task 50004', completed: false },
t2148bf88: { title: 'Task 50005', completed: false },
t9e37b9b6: { title: 'Task 50006', completed: false },
tb5b1b6ae: { title: 'Task 50007', completed: false },
tfe88b26d: { title: 'Task 50008', completed: false },
(100,000 items)
})

// 使用

function toggleTodo (todos, id) {
return u({

completed: (completed) => !completed}

}, todos)

}

var nextState = toggleTodo(todos, 't2148bf88')这项操作运行了1.2ms。速度提升了100倍。

为什么会这么快呢?

可持久化的数据结构

可持久化的数据结构强制约束所有的操作将返回新版本数据结构并且保持原有的数据结构不变,而不是直接修改原来的数据结构。

这意味着:所有的可持久化数据结构是不可变的。
鉴于这个约束,第三方库在应用可持久化数据结构后可以更好的优化性能。

性能提升

为了直观的观察,让我们尝试一个小小例子。

键值对映射数据:
为什么用Immutable.js代替普通js对象?
我们可以用一个普通的JavaScript对象来保存:
const data = {
to: 7,
tea: 3,
ted: 4,
ten: 12,
A: 15,
i: 11,
in: 5,
inn: 9
}
转换成一棵数据树,像这样:

为什么用Immutable.js代替普通js对象?

图片来源: 维基百科
通常来讲,你可以从根节点沿着上图的路径来获取你想要的值。
如果你想获取data.in,从根节点开始,沿着i,n,就可以到达值为5的节点。
如何去修改呢?
比如我们想把键为tea的值3改成14。
我要建造一个新的树,并且尽可能重用已经存在的节点
为什么用Immutable.js代替普通js对象?
绿色表示新建的节点。
为什么用Immutable.js代替普通js对象?
灰色的节点失去的索引,将会被回收
正如你所看到的,我们只是重新创建了4个新的节点来更新这个树。其他节点都被重用了。
这叫 结构共享
Immutable.js就是通过这种方式实现Immutable.Map。创建一个树,每个节点最多有32个分支。
为什么用Immutable.js代替普通js对象?
这张图展示了一个真实的Immutable.Map
当我们更新一个节点,只有几个节点需要被重新创建。
Immutable.js通过创建多种类型的节点来保持树结构的紧凑和性能:

为什么用Immutable.js代替普通js对象?

万物皆有两面性

请不要认为这篇文章的意思是“你应该经常使用Immutable.js。”,准确的讲,我只是告诉你用它的所有好处,以及为什么要使用它。

当我在写代码的时候,我首先会用普通的JavaScript对象和数组,当我使用Immutable.js时,我需要非常确定,比如一个对象包含10,000个属性。我几乎从不使用Immutable.js,因为大多数时候的对象都很小。

作者:缪宇

链接:
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的文章
《IPv6安全》——1.7 推荐读物和资料
查看>>
《实施Cisco统一通信管理器(CIPT2)》一1.2 概述部署多站点环境时将会遇到的挑战...
查看>>
《CCNP安全Secure 642-637认证考试指南》——第8章 配置与实施路由式数据面安全...
查看>>
AngularJS 的自定义指令
查看>>
《CCNA ICND2(200-101)认证考试指南(第4版)》——第1章定义生成树协议
查看>>
什么样的 RPC 才是好用的 RPC
查看>>
《Adobe Premiere Pro CC经典教程》——14.6 特殊颜色效果
查看>>
Debian 项目不再提供 CD 格式的 ISO 镜像
查看>>
《设计团队协作权威指南》—第1章1.3节甘为螺丝钉
查看>>
android 屏幕保持唤醒 不锁屏 android.permission.WAKE_LOCK
查看>>
《Unity 3D 游戏开发技术详解与典型案例》——1.3节第一个Unity 3D程序
查看>>
Airbnb数据科学团队进化论:如何由内而外实现数据驱动
查看>>
如何用机器学习预测超售,避免美联航“暴力赶客”悲剧
查看>>
css细节(实习第1天)
查看>>
腾讯Android自动化测试实战3.1.4 Robotium的控件获取、操作及断言
查看>>
《C语言点滴》一1.5 内功修炼
查看>>
浅析 Linux 初始化 init 系统: UpStart
查看>>
《PHP和MySQL Web开发从新手到高手(第5版)》一1.7 万事俱备,摩拳擦掌
查看>>
linux 怎么完全卸载mysql数据库
查看>>
Dart的HTTP请求和响应(1)
查看>>