Record 和 Tuple 是 JavaScript 新增的原生不可变复合数据结构,提供深度不可变性与结构相等性,解决普通对象/数组因可变和引用比较导致的缓存、状态比较等问题。

JavaScript 长期缺乏原生的、不可变的复合数据结构,导致开发者在需要值语义(value semantics)或结构相等性(structural equality)时,不得不依赖第三方库(如 Immutable.js)或手动封装,既增加开销,又难以保证真正不可变。Record 和 Tuple 提案正是为填补这一空白而设计——它们提供语法简洁、运行时高效、深度不可变的原生类型,让对象和数组的“不可变版本”第一次成为语言一级公民。
解决对象/数组默认可变带来的问题
普通对象和数组是引用类型且可变:修改其属性或元素不会产生新值,也无法安全地用 === 判断内容是否相同。例如:
[1, 2] === [1, 2] // false
这使得缓存、状态比较(如 React 的 useMemo 或 React.memo)、持久化数据结构等场景容易出错或低效。Record 和 Tuple 通过强制不可变 + 值相等,直接解决这些问题。
Record:不可变的对象字面量
Record 是键名固定、键值类型受限的不可变映射,语法类似对象字面量但用 # 开头:
立即学习“Java免费学习笔记(深入)”;
#{{ name: "Alice", age: 30 }}- 创建后所有属性只读,不能增删改;嵌套的 Record/Tuple 也自动冻结
-
===比较基于内容而非引用:两个结构相同的 Record 恒等 - 键名必须是字符串字面量(不支持动态计算),值只能是原始类型、Record、Tuple、null、undefined 或 bigint
Tuple:不可变的有序集合
Tuple 是长度固定、类型灵活的不可变数组,语法类似数组字面量但用 # 开头:
- 长度和每个位置的值在创建后锁定,不能 push/pop/splice
- 支持混合类型,也支持嵌套 Record/Tuple,整个结构深度不可变
- 同样支持
===结构相等:#[1,2] === #[1,2]返回true
与现有方案的本质区别
不同于 Object.freeze() 或 Immutable.js:
-
Object.freeze()只做浅冻结,嵌套对象仍可变;Record/Tuple 是深度、递归不可变 - 第三方库需额外打包体积、学习成本,且无法被引擎深度优化;Record/Tuple 是原生语法,V8 等引擎可针对性优化内存布局与比较逻辑
- 值相等是默认行为,无需调用
is()或deepEqual(),天然适配 Map/Set 键、React 依赖追踪等场景











