深入理解 You Don't Know JS: ES6 集合类型详解

深入理解 You Don't Know JS: ES6 集合类型详解

You-Dont-Know-JS 📗📒 (PT-Br translation) JS Book Series. You-Dont-Know-JS 项目地址: https://gitcode.com/gh_mirrors/you/You-Dont-Know-JS

前言

在 JavaScript 开发中,数据集合的组织和访问是几乎所有程序的核心部分。从语言诞生之初,数组(Array)和对象(Object)就是我们构建数据结构的主要工具。ES6 引入了几种新的集合类型,为开发者提供了更强大、更高效的数据处理能力。

本文将深入探讨 ES6 中的 TypedArrays、Map、Set 以及它们的弱引用版本 WeakMap 和 WeakSet,帮助开发者更好地理解和使用这些重要的数据结构。

TypedArrays:处理二进制数据的利器

TypedArrays(类型化数组)实际上在 ES5 时期就已经存在,主要用于 WebGL 等场景。ES6 将其正式纳入语言规范,使其成为 JavaScript 的一等公民。

基本概念

TypedArrays 并不是存储特定类型值的数组,而是提供了对二进制数据的结构化访问机制。它由两部分组成:

  1. ArrayBuffer:原始的二进制数据缓冲区
  2. 视图(View):解释缓冲区数据的类型化数组
// 创建32字节(256位)的缓冲区
const buf = new ArrayBuffer(32)
buf.byteLength // 32

字节序问题

字节序(Endianness)指的是多字节数据在内存中的存储顺序,分为大端序(Big-Endian)和小端序(Little-Endian)。TypedArrays 会使用运行平台的字节序,这可能在不同系统间交换数据时造成问题。

可以通过以下方法检测当前环境的字节序:

const littleEndian = (function() {
  const buffer = new ArrayBuffer(2)
  new DataView(buffer).setInt16(0, 256, true)
  return new Int16Array(buffer)[0] === 256
})()

多重视图

同一个缓冲区可以附加多个不同类型的视图:

const buf = new ArrayBuffer(2)
const view8 = new Uint8Array(buf)
const view16 = new Uint16Array(buf)

view16[0] = 3085
view8[0] // 13
view8[1] // 12

TypedArray 构造函数

ES6 提供了多种 TypedArray 类型:

  • Int8Array/Uint8Array (8位有/无符号整数)
  • Uint8ClampedArray (8位无符号整数,值固定在0-255)
  • Int16Array/Uint16Array (16位有/无符号整数)
  • Int32Array/Uint32Array (32位有/无符号整数)
  • Float32Array (32位浮点数)
  • Float64Array (64位浮点数)

TypedArray 与普通数组类似,但长度固定且元素类型一致。它们共享大部分数组方法,但不支持会改变数组长度的方法如 push/pop 等。

Map:真正的键值对集合

传统 JavaScript 对象作为键值对集合使用时有个重大限制:键只能是字符串。Map 解决了这个问题,允许使用任意类型的值作为键。

基本用法

const m = new Map()
const x = { id: 1 }, y = { id: 2 }

m.set(x, "foo")
m.set(y, "bar")

m.get(x) // "foo"
m.get(y) // "bar"

Map 操作方法

  • set(key, value):添加键值对
  • get(key):获取值
  • delete(key):删除键值对
  • clear():清空Map
  • size:获取键值对数量

遍历Map

Map 提供了三种遍历方法:

// 遍历值
const vals = [...m.values()] // ["foo", "bar"]

// 遍历键
const keys = [...m.keys()] // [x, y]

// 遍历键值对
const entries = [...m.entries()]
// [[x, "foo"], [y, "bar"]]

WeakMap:弱引用Map

WeakMap 与 Map 类似,但有几点关键区别:

  1. 只接受对象作为键
  2. 键是弱引用(不影响垃圾回收)
  3. 没有遍历方法和size属性
const wm = new WeakMap()
const x = { id: 1 }

wm.set(x, "private data")

// 当x不再被引用时,wm中的条目会被自动清除

WeakMap 非常适合存储对象的私有数据或元数据,因为当对象被回收时,相关数据也会自动清除,避免内存泄漏。

Set:值唯一的集合

Set 类似于数组,但成员值都是唯一的:

const s = new Set()

s.add(1).add(2).add(1)

s.size // 2
s.has(1) // true

WeakSet:弱引用Set

WeakSet 与 Set 的区别:

  1. 只能存储对象值
  2. 值是弱引用
  3. 不可遍历
const ws = new WeakSet()
const x = { id: 1 }

ws.add(x)
ws.has(x) // true

总结

ES6 新增的集合类型为 JavaScript 开发者提供了更强大的工具:

  1. TypedArrays 提供了处理二进制数据的能力
  2. Map/Set 解决了传统对象和数组的限制
  3. WeakMap/WeakSet 提供了更好的内存管理

这些新特性使得 JavaScript 能够更好地处理复杂数据结构和内存敏感的场景,是每个现代 JavaScript 开发者都应该掌握的技能。

You-Dont-Know-JS 📗📒 (PT-Br translation) JS Book Series. You-Dont-Know-JS 项目地址: https://gitcode.com/gh_mirrors/you/You-Dont-Know-JS

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余伊日Estra

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值