拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

TypeScript Symbol 全面指南:全局唯一原始值、对象键与弱集合应用(The Concise TypeScript Book 系列)

TypeScript Symbol 全面指南:全局唯一原始值、对象键与弱集合应用(The Concise TypeScript Book 系列) 文档教程【免费下载链接】typescript-bookThe Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.项目地址https://gitcode.com/gh_mirrors/typ/typescript-book点击查看免费下载Symbol 是 TypeScript 中一种特殊的原始数据类型其值在程序整个生命周期内被保证全局唯一且不可变。本文以《The Concise TypeScript Book》的 Symbol 章节 为骨架系统讲解 Symbol 作为对象属性键、实现不可枚举属性、以及作为 WeakMap / WeakSet 键的完整用法并延伸讲解符号索引签名、知名符号Well-known Symbols等进阶场景。读完你将掌握在对象、集合与底层协议迭代、资源释放、装饰器元数据中正确使用 Symbol 的实战能力。Symbol 是什么全局唯一的原始数据类型Symbol 是 JavaScript / TypeScript 中 7 种原始数据类型之一其余为string、boolean、number、bigint、null、undefined详见仓库中的 Primitive Types 章节。作为原始类型它不可变immutable一旦创建其值无法被修改全局唯一globally unique每次调用Symbol()都会产生一个全新的、与其他任何 Symbol 都不相等的值即使传入相同的描述字符串非对象没有与对象关联的方法不参与常规的类型强制转换。在 TypeScript 中可以用symbol类型注解声明一个 Symbol 变量const key1: symbol Symbol(key1); const key2: symbol Symbol(key2);这里key1与key2只是可选的描述字符串description用于调试和日志输出并不参与唯一性判定——即便两个 Symbol 的描述相同它们依然是两个不同的值。Symbol 作为对象属性键Symbol 最常见的用途是作为对象属性的键key。由于每个 Symbol 都全局唯一用它做键可以彻底避免命名冲突这是字符串键无法保证的。原文档给出的核心示例const key1: symbol Symbol(key1); const key2: symbol Symbol(key2); const obj { [key1]: value 1, [key2]: value 2, }; console.log(obj[key1]); // value 1 console.log(obj[key2]); // value 2要点计算属性名[key1]语法允许把变量作为属性键读取时同样使用obj[key1]不能使用点号语法两个不同 Symbol 键互不干扰即使描述字符串相同obj[key1]与obj[key2]也指向不同的属性。枚举行为Symbol 键与普通字符串键的区别原文档指出 Symbol 键提供了一种创建不可枚举属性的途径。更精确地说Symbol 键属性不会被for...in循环和Object.keys()枚举但它们仍然真实存在于对象上可以通过Object.getOwnPropertySymbols()或Reflect.ownKeys()获取const key: symbol Symbol(hidden); const obj { visible: 1, [key]: 2, }; console.log(Object.keys(obj)); // [visible] console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(hidden)] console.log(Reflect.ownKeys(obj)); // [visible, Symbol(hidden)]这种特性非常适合存放元数据性质的内部状态既不影响外部遍历又能保持对象结构的完整性。类型层面的 symbol索引签名与符号键类型在 TypeScript 中symbol不仅是一个值也是一个类型。它可以用在索引签名中声明以任意 Symbol 为键的对象形状。仓库中的 Primitive Types 章节 给出了这一模式type Obj { [sym: symbol]: number; }; const a Symbol(a); const b Symbol(b); let obj: Obj {}; obj[a] 123; obj[b] 456; console.log(obj[a]); // 123 console.log(obj[b]); // 456此外从 TypeScript 4.4 开始索引签名支持Symbol 键与模板字符串模式键这在仓库的 Others 章节 中有完整示例const uniqueSymbol Symbol(description); type MyKeys key-${string}; type MyObject { [uniqueSymbol]: string; [key: MyKeys]: number; }; const obj: MyObject { [uniqueSymbol]: Unique symbol key, key-a: 123, key-b: 456, }; console.log(obj[uniqueSymbol]); // Unique symbol key console.log(obj[key-a]); // 123 console.log(obj[key-b]); // 456这里展示了两种具体键的组合能力[uniqueSymbol]: string用具体 Symbol 实例作为键[key: MyKeys]: number用模板字符串模式匹配所有以key-开头的字符串键。Symbol 在 WeakMap 与 WeakSet 中的使用原文档特别指出在 WeakMap 和 WeakSet 中Symbol 现在可以作为键使用。WeakMap 的键过去只允许是对象object因为弱引用需要可进行垃圾回收的目标。当 Symbol 作为键时必须使用Symbol.for()/Symbol.keyFor()注册表机制创建的注册 Symbol才可被全局复用这是它能够参与弱引用语义的前提。基本用法示例const privateData new WeakMapsymbol, string(); const key Symbol(user-id); privateData.set(key, data-for-this-key); console.log(privateData.get(key)); //>class NumberIterator implements Iterablenumber { private current: number; constructor( private start: number, private end: number ) { this.current start; } public next(): IteratorResultnumber { if (this.current this.end) { const value this.current; this.current; return { value, done: false }; } else { return { value: undefined, done: true }; } } [Symbol.iterator](): Iteratornumber { return this; } } const iterator new NumberIterator(1, 3); for (const num of iterator) { console.log(num); }只要实现[Symbol.iterator]()方法对象就可以被for...of循环消费同时也能配合展开运算符、解构等语法使用。Symbol.dispose 与 Symbol.asyncDispose资源释放协议从 TypeScript 5.2 开始using与await using声明配合Symbol.dispose/Symbol.asyncDispose实现了确定性的资源管理。仓库中的 Others 章节 给出了典型示例//ts-ignore Symbol.dispose ?? Symbol(Symbol.dispose); // Simple polyfill const doWork (): Disposable { return { [Symbol.dispose]: () { // 释放资源的逻辑 }, }; };由于这些符号在多数运行时环境中尚缺乏原生支持需要为Symbol.dispose、Symbol.asyncDispose、DisposableStack、AsyncDisposableStack、SuppressedError提供 polyfill如上面的??简单实现。Symbol.metadata装饰器元数据入口在 TypeScript 5.2 的类装饰器提案中Symbol.metadata是装饰器元数据的统一入口仓库的 Class 章节 展示了其 polyfill 与使用方式//ts-ignore Symbol.metadata ?? Symbol(Symbol.metadata); // Simple polyfill type Context | ClassFieldDecoratorContext // ... 其他装饰器上下文类装饰器通过MyClass[Symbol.metadata]可以读取到由各装饰器写入的元数据信息。小结Symbol 在 TypeScript 中扮演着三重角色唯一标识符作为对象属性键防止命名冲突并让键不出现在Object.keys()等常规枚举中类型系统的一部分symbol类型可用于索引签名从 TypeScript 4.4 起支持以具体 Symbol 实例为键的索引签名协议接入点通过Symbol.iterator、Symbol.dispose、Symbol.metadata等知名符号让对象与语言内置的迭代、资源释放、装饰器元数据等机制无缝对接。相关主题可继续深入阅读仓库内的 Symbols 章节英文原版、Primitive Types、Others索引签名与资源管理 以及 Class装饰器元数据。赞分享文档教程【免费下载链接】typescript-bookThe Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.项目地址https://gitcode.com/gh_mirrors/typ/typescript-book点击查看免费下载相关推荐TypeScript 中的 symbol 类型全局唯一原始类型与对象属性键实战指南The Concise TypeScript Book 解读TypeScript 中的 symbol 类型全局唯一原始类型与对象属性键实战指南The Concise TypeScript Book 解读 本文基于文档教程TypeScript 符号Symbol详解全局唯一值、对象属性键与 WeakMap/WeakSet 键支持 —— 基于 The Concise TypeScript Book 源码TypeScript 符号Symbol详解全局唯一值、对象属性键与 WeakMap/WeakSet 键支持 —— 基于 The Concise TypeS文档教程The Concise TypeScript Book Symbols 章节深度解读Symbol 原始类型的唯一性、属性键与弱集合应用The Concise TypeScript Book Symbols 章节深度解读Symbol 原始类型的唯一性、属性键与弱集合应用 本文以《The Con文档教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表