封面
Bit fields(bit vectors)
Bitfield 是比较底层的一种数据结构. 可以理解为全部是由 0 和 1 组成的数组, 熟悉 c++ 编程可能对这部分内容不会感觉陌生, 其实 Bitfield 就是一种数据结构. JavaScript 也提供定义 bitFields ,0b 前缀表示是 bitField 的类型数据.
bit fields
具体定义方法如下
let effectTag = 0b01010001;//81
在 React 使用 Bitfield 来表示侧边效应. react 中的侧边效应通常都是对 DOM 元素执行的操作, 例如可能在 DOM 中放置一个元素, 更新标签 (元素), 删除元素. 在 React 中不是用字符串数组来记录这些操作, 而是用 Bitfield 数据结构来记录和表示这些对 DOM 的操作.
侧边效应表示
下面通过一个例子来说明, 通过对类型为 span 标签进行更新来观察 effectTag 的变化.
tag
effectTag 0 表示渲染前的阶段
effectTag 4 表示渲染后的阶段
effectTag 为 0 , 则意味着对 span 无需执行任何操作. 当我调试 React 时, 跟踪 span 元素, 更新了 span 元素上的标记, 如果想要弄清楚 span 是如何变化., 可以通过 bitfil, 所以在渲染面有进程改变之后, effectTag 变为 4, 因为类型为 bitfil, 是二进制的, 所以转换为十进制的, 实际上是二进制 100. 也就是第三位是 1, 这和我们期望一致.
- const effectTags = {
- Placement : 0b000000000010,
- Update : 0b000000000100,
- PlacementAndUpate : 0b000000000110,
- ...
- }
React 对 DOM 更新操作进行了编码, 接下来 React 将检查每个位, 并查看其对应要执行什么类型的操作. 例如, update 将更新标记.
- function updateHostEffects(fiberNode){
- const effectTag = fiberNode.effectTag;
- if(effectTag & effectTags.Placement){};
- if(effectTag & effectTags.Update){};
- if(effectTag & effectTags.PlacementAndUpate){};
- }
为什么要这么麻烦呢, 直接用对象不行吗? 那么接下来我们就看一看 bitfil 相对于其他类型的数据结构所具有的优势.
例如, 使用 Bitfil 数据结构, 就不需要为 JavaScript 对象和 shape 分配内存, 因此虚拟机可以节省大量空间, 而且由于没有 shape 和 JavaScript 对象, 因此没有引用, 垃圾回收也变的简单得多. 不然根据对象依赖关系图, 知道哪些对象是否可以被安全回收的. 对于 bitfils , 一个指令就让处理器清除存储器, 就是这样简单.
bitfil 使用一个较小的连续内存, 并实现对其快速的访问. 因此在 Angular 和 React 中都使用了这种数据结构.
最后希望大家关注我们微信公众号
wechat.jpeg
来源: http://www.jianshu.com/p/2fbca5fa4b44