红宝书——06.集合应用类型02()

目录

1.定型数组

1.来源

2.ArrayBuffer

3.DataView

2.Map

1.基本API        

2.迭代和顺序

3.map和object的选择

1.内存占用

2.插入性能

3.查找速度

4.删除性能

3.WeakMap

1.基本 API

2.弱键

3.不可迭代键

4.使用弱映射

1.私有变量

2.DOM 节点元数据


1.定型数组

定型数组(typed array)是 ECMAScript 新增的结构,目的是提升向原生库传输数据的效率。实际上,   JavaScript 并没有“TypedArray”类型,它所指的其实是一种特殊的包含数值类型的数组。

1.来源

在 WebGL 的早期版本中,因为 JavaScript 数组与原生数组之间不匹配,所以出现了性能问题。图形驱动程序 API 通常不需要以 JavaScript 默认双精度浮点格式传递给它们的数值,而这恰恰是 JavaScript数组在内存中的格式。

Mozilla 为解决这个问题而实现了 CanvasFloatArray 。这是一个提供JavaScript接口的、C语言风格的浮点值数组。最终, CanvasFloatArray变成了 Float32Array ,也就是今天定型数组中可用的第一个“类型”。

2.ArrayBuffer

ArrayBuffer() 是一个普通的 JavaScript 构造函数,可用于在内存中分配特定数量的字节空间。
const buf = new ArrayBuffer(16); // 在内存中分配 16 字节
alert(buf.byteLength); // 16


ArrayBuffer 一经创建就不能再调整大小。但可以使用 slice() 复制其全部或部分到一个新实例中:
const buf1 = new ArrayBuffer(16);
const buf2 = buf1.slice(4, 12);
alert(buf2.byteLength); // 8

3.DataView

须在对已有的 ArrayBuffer 读取或写入时才能创建 DataView 实例。这个实例可以使用全部或部分 ArrayBuffer ,且维护着对该缓冲实例的引用,以及视图在缓冲中开始的位置。
const buf = new ArrayBuffer(16);
// DataView 默认使用整个 ArrayBuffer
const fullDataView = new DataView(buf);
alert(fullDataView.byteOffset); // 0
alert(fullDataView.byteLength); // 16
alert(fullDataView.buffer === buf); // true

4.定型数组

定型数组是另一种形式的 ArrayBuffer 视图。虽然概念上与 DataView 接近,但定型数组的区别
在于,它特定于一种 ElementType 且遵循系统原生的字节序。

2.Map

作为 ECMAScript 6 的新增特性, Map 是一种新的集合类型,为这门语言带来了真正的键/值存储机制。 Map 的大多数特性都可以通过 Object 类型实现,但二者之间还是存在一些细微的差异。

1.基本API        

// 使用嵌套数组初始化映射
const m1 = new Map([
["key1", "val1"],
["key2", "val2"],
["key3", "val3"]
]);
alert(m1.size); // 3
// 使用自定义迭代器初始化映射
const m2 = new Map({
[Symbol.iterator]: function*() {
yield ["key1", "val1"];
yield ["key2", "val2"];
yield ["key3", "val3"];
}
});
alert(m2.size); // 3

set() 方法再添加键/值对。另外,可以使用 get() 和 has() 进行查询。

与 Object 只能使用数值、字符串或符号作为键不同, Map 可以使用任何 JavaScript 数据类型作为键。 

2.迭代和顺序

与 Object 类型的一个主要差异是, Map 实例会维护键值对的插入顺序,因此可以根据插入顺序执
行迭代操作。

可以通过 entries() 方法(或者 Symbol.iterator 属性,它引用 entries() )取得这个迭代器。

 

3.map和object的选择

1.内存占用

不同浏览器的情况不同,但给定固定大小的内存, Map 大约可以比 Object 多存储 50%的键/值对。

2.插入性能

 Map 在所有浏览器中一般会稍微快一点儿如果代码涉及大量插入操作,那么显然 Map 的性能更佳。

3.查找速度

在把 Object 当成数组使用的情况下(比如使用连续整数作为属性),浏览器引擎可以进行优化,在内存中使用更高效的布局。如果代码涉及大量查找操作,那么某些情况下可能选择 Object 更好一些。

4.删除性能

对大多数浏览器引擎来说, Map 的 delete() 操作都比插入和查找更快。如果代码涉及大量删除操作,那么毫无疑问应该选择 Map 。        

3.WeakMap

ECMAScript 6 新增的“弱映射”( WeakMap )是一种新的集合类型,为这门语言带来了增强的键/
值对存储机制。 WeakMap 是 Map 的“兄弟”类型,其 API 也是 Map 的子集。  WeakMap 中的“weak”(弱),描述的是 JavaScript 垃圾回收程序对待“弱映射”中键的方式。

1.基本 API

const wm = new WeakMap();

弱映射中的键只能是 Object 或者继承自 Object 的类型,尝试使用非对象设置键会抛出
TypeError 。值的类型没有限制。

初始化之后可以使用 set() 再添加键/值对,可以使用 get() 和 has() 查询,还可以使用 delete()
删除

2.弱键

const wm = new WeakMap();
wm.set({}, "val");
set() 方法初始化了一个新对象并将它用作一个字符串的键。因为没有指向这个对象的其他引用
所以当这行代码执行完成后,这个对象键就会被当作垃圾回收。然后,这个键/值对就从弱映射中消失了,使其成为一个空映射

const wm = new WeakMap();
const container = {
key: {}
};
wm.set(container.key, "val");
function removeReference() {
container.key = null;
}
这一次, container 对象维护着一个对弱映射键的引用,因此这个对象键不会成为垃圾回收的目
标。不过,如果调用了 removeReference() ,就会摧毁键对象的最后一个引用,垃圾回收程序就可以把这个键/值对清理掉。

3.不可迭代键

因为 WeakMap 中的键/值对任何时候都可能被销毁,所以没必要提供迭代其键/值对的能力。

4.使用弱映射

1.私有变量

弱映射造就了在 JavaScript 中实现真正私有变量的一种新方式。前提很明确:私有变量会存储在弱映射中,以对象实例为键,以私有成员的字典为值。

外部代码只需要拿到对象实例的引用和弱映射,就可以取得“私有”变量了。为了避免这种访问,可以用一个闭包把 WeakMap 包装起来,这样就可以把弱映射与外界完全隔离开了。

2.DOM 节点元数据

因为 WeakMap 实例不会妨碍垃圾回收,所以非常适合保存关联元数据。

当节点从 DOM 树中被删除后,垃圾回收程序就可以立即释放其内存(假设没有其他地方引用这个对象):
const wm = new WeakMap();
const loginButton = document.querySelector('#login');
// 给这个节点关联一些元数据
wm.set(loginButton, {disabled: true});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值