Symbol 是 JavaScript 中唯一、不可变的原始类型,用于创建防冲突的私有属性键或对接语言机制(如 Symbol.iterator);它不参与隐式转换,不可枚举,不被 JSON 序列化,需用方括号访问。

Symbol 是 JavaScript 中的原始类型,用来创建唯一、不可变的标识符
它不是字符串,也不能被隐式转换成字符串(除非显式调用 toString()),更不会参与对象属性名的自动类型转换。一个 Symbol() 调用总会返回一个新值,哪怕描述相同:Symbol('a') !== Symbol('a')。这点决定了它天然适合做“防冲突”的键。
用 Symbol 作为对象属性名,避免命名污染
当多个模块/库向同一个对象注入方法或元数据时,普通字符串键容易撞车。用 Symbol 可以确保隔离:
const isReady = Symbol('isReady');
const cacheKey = Symbol('cacheKey');
const obj = {
[isReady]: false,
[cacheKey]: null
};
// 外部代码遍历 Object.keys(obj) 或 for...in 都看不到这两个属性
// 只有通过 Object.getOwnPropertySymbols(obj) 才能拿到
- 不被
JSON.stringify()序列化 - 不被
Object.assign()拷贝(除非手动提取getOwnPropertySymbols) - 不能用点操作符访问:
obj.isReady是undefined,必须用方括号:obj[isReady]
利用全局 Symbol 注册表实现跨模块共享符号
如果需要多个地方引用同一个 Symbol(比如统一的事件类型标识),要用 Symbol.for(key):
本文档主要讲述的是Android的资源与国际化设置;资源是外部文件(不含代码的文件),它被代码使用并在编译时编入应用程序。Android支持不同类型的资源文件,包括XML,PNG以及JPEG文件XML文件根据描述的不同有不同格式。这份文档描述可以支持什么样的文件,语法,以及各种格式。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
const eventCancel = Symbol.for('event.cancel');
const sameRef = Symbol.for('event.cancel');
console.log(eventCancel === sameRef); // true
-
Symbol.for()查找全局注册表,不存在则创建并登记;Symbol()每次都新建 - 对应可查注册名:
Symbol.keyFor(eventCancel)返回'event.cancel' - 注意:全局注册表是跨 realm 的(比如 iframe 之间也能共享),但名字字符串本身无作用域控制,起名仍需谨慎
内置 Symbol(如 Symbol.iterator)让对象支持语言级语法
JavaScript 引擎在遇到 for...of、展开运算符、Array.from() 等时,会自动查找对象上的 [Symbol.iterator] 方法。你可以自己实现迭代逻辑:
立即学习“Java免费学习笔记(深入)”;
const countdown = {
from: 3,
[Symbol.iterator]() {
return {
current: this.from,
next() {
if (this.current > 0) {
return { value: this.current--, done: false };
}
return { done: true };
}
};
}
};
[...countdown]; // [3, 2, 1]
- 其他常用内置 Symbol:
Symbol.toStringTag(影响Object.prototype.toString.call(x)输出)、Symbol.hasInstance(自定义instanceof行为)、Symbol.toPrimitive(控制对象转原始值) - 这些都不是“魔法”,只是引擎约定好的查找路径;没实现就走默认逻辑(比如报
TypeError: x is not iterable)
for...of)。其余场景,字符串键更直白、更易调试。










