Symbol 是 JavaScript 的第七种原始类型,专为解决属性名冲突和封装问题设计,其值天然唯一、不可枚举、不可隐式转换,必须用方括号访问,支持 Symbol.for() 跨模块共享及内置 Symbol 协议扩展对象行为。

Symbol 是 JavaScript 的第七种原始类型,**不是“用来学的教程概念”,而是解决真实冲突和封装问题的工具**——它生成的值天然唯一、不可枚举、不可隐式转换,专为属性键设计。
为什么用 Symbol 而不用字符串当属性名?
因为字符串属性名容易撞车,尤其在多人协作、混用第三方库或动态扩展对象时。Symbol 一创建就“自带防重命名锁”:
-
Symbol('id')和Symbol('id')不相等 —— 每次调用都返回新值 - 即使描述相同:
const a = Symbol('user'); const b = Symbol('user');,a === b仍为false - 它不会出现在
for...in、Object.keys()、JSON.stringify()中,天然“隐身”
Symbol 怎么用?关键三步别写错
常见错误是误以为带描述就能复用,或试图用点号访问 —— 这俩都会失败:
- ✅ 正确创建:
const id = Symbol('user_id');(描述仅用于调试,不影响值) - ✅ 正确赋值:
obj[id] = 123;(必须用方括号,obj.id读不到) - ❌ 错误操作:
obj.Symbol('id')或obj.id—— 会得到undefined - ✅ 查看 Symbol 属性:
Object.getOwnPropertySymbols(obj),不是Object.keys()
什么时候该用 Symbol.for()?
只有当你需要跨模块/跨文件共享同一个 Symbol 时才用它,比如定义统一的事件类型或插件钩子:
const EVENT_CLICK = Symbol.for('ui.click');- 同一
key多次调用Symbol.for()返回同一个 Symbol,Symbol.keyFor(EVENT_CLICK)可反查 key - ⚠️ 注意:全局注册表是共享的,避免用太泛的 key(如
'data'),推荐加命名空间:'mylib:cacheKey'
内置 Symbol(如 Symbol.iterator)不是装饰,是协议入口
它们不是“高级语法糖”,而是 JS 引擎识别并调用的约定接口。比如让自定义对象支持 for...of:
本文档主要讲述的是Android的资源与国际化设置;资源是外部文件(不含代码的文件),它被代码使用并在编译时编入应用程序。Android支持不同类型的资源文件,包括XML,PNG以及JPEG文件XML文件根据描述的不同有不同格式。这份文档描述可以支持什么样的文件,语法,以及各种格式。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
立即学习“Java免费学习笔记(深入)”;
const list = {
[Symbol.iterator]() {
let i = 0;
return {
next() {
return i < 3 ? { value: i++, done: false } : { done: true };
}
};
}
};
for (const n of list) console.log(n); // 0, 1, 2
其他常用内置 Symbol:Symbol.toStringTag(改 Object.prototype.toString() 输出)、Symbol.hasInstance(定制 instanceof 行为)—— 它们只在你需要深度控制语言行为时才介入。
Symbol,而是判断「这里是否真的需要它」:多数业务对象不需要隐藏属性,多数常量也不必用 Symbol 替代字符串;但一旦你开始写工具库、拦截原型、设计插件系统,Symbol 就从可选项变成安全底线。










