symbol 是为解决对象属性名冲突而引入的原始数据类型,每个 symbol 值都是唯一的。1. 创建方式是调用 symbol() 函数,如 const id = symbol("id");2. 常见用途包括作为对象的唯一键名、避免命名冲突、使用知名 symbol 实现语言特性,例如 symbol.iterator 支持迭代;3. 注意事项有 symbol 不参与 json 序列化、不会被 object.assign() 复制,需用 symbol.for() 共享 symbol。

Symbol 是 JavaScript 中的一种原始数据类型,用来创建唯一的标识符。它在 ES6(ECMAScript 2015)中被引入,主要是为了解决对象属性名冲突的问题。简单来说,每个 Symbol 值都是独一无二的,不会和其他任何值相等,即使它们的描述完全一样。
为什么用 Symbol?
在 Symbol 出现之前,对象的属性名只能是字符串。如果你在一个对象上添加了一个属性,而这个属性名刚好和别人写的代码中的属性名重复了,就可能引发意想不到的问题。比如:
const user = {
name: "Alice"
};
// 其他人可能会不小心覆盖掉你定义的属性
user.name = "Bob";虽然这只是一个简单的例子,但在大型项目或库中,这种情况更容易发生。Symbol 提供了一种方式来创建“私有”属性,避免命名冲突。
怎么创建一个 Symbol?
创建 Symbol 非常简单,使用 Symbol() 函数即可:
const id = Symbol("id");这里的 "id" 是对这个 Symbol 的描述,主要用于调试时识别,不影响它的唯一性。
需要注意的是:
- 每次调用
Symbol()都会生成一个新的、唯一的值。 - 不要使用
new来创建 Symbol,否则会报错。
Symbol 的常见用途
1. 作为对象的唯一键名
这是 Symbol 最常见的用法之一:
技术上面应用了三层结构,AJAX框架,URL重写等基础的开发。并用了动软的代码生成器及数据访问类,加进了一些自己用到的小功能,算是整理了一些自己的操作类。系统设计上面说不出用什么模式,大体设计是后台分两级分类,设置好一级之后,再设置二级并选择栏目类型,如内容,列表,上传文件,新窗口等。这样就可以生成无限多个二级分类,也就是网站栏目。对于扩展性来说,如果有新的需求可以直接加一个栏目类型并新加功能操作
const user = {};
const id = Symbol("id");
user[id] = "12345";
console.log(user[id]); // 输出 12345这样做的好处是:这个属性不会被枚举到,也不会出现在 Object.keys() 或 for...in 循环中。
2. 避免命名冲突
多个模块或库之间共享一个对象时,使用 Symbol 可以避免属性名冲突。例如:
const myLib = {
[Symbol("version")]: "1.0.0"
};其他库就算也用了 "version" 这个名字,也不会冲突。
3. 使用知名 Symbol 实现语言特性
JavaScript 内置了一些知名的 Symbol,用于定义一些特殊行为,比如:
-
Symbol.iterator:让对象可以被迭代(如用for...of遍历) -
Symbol.toPrimitive:控制对象转原始值的行为 -
Symbol.toStringTag:自定义对象的toString()返回值
例如,你可以自定义一个可迭代的对象:
const myIterable = {
[Symbol.iterator]() {
let step = 0;
return {
next() {
step++;
return { value: step, done: step > 3 }
}
};
}
};
for (let val of myIterable) {
console.log(val); // 输出 1, 2, 3
}注意事项
- Symbol 类型不能参与 JSON 序列化,也就是说用
JSON.stringify()会忽略 Symbol 属性。 - 如果你想全局共享某个 Symbol,可以用
Symbol.for(key)和Symbol.keyFor(sym)。 - Symbol 不会被
Object.assign()或扩展运算符自动复制。
基本上就这些了。Symbol 虽然看起来不复杂,但在实际开发中特别适合用来做“隐藏”的标识符或者防止属性冲突,用起来也很灵活。









