js symbol实现
Symbol 的基本概念
Symbol 是 JavaScript 中的一种原始数据类型,用于创建唯一的标识符。每个 Symbol 值都是独一无二的,即使它们的描述相同。Symbol 的主要用途是为对象添加唯一的属性键,避免属性名冲突。
创建 Symbol
通过 Symbol() 函数可以创建一个 Symbol 值。可以传入一个可选的描述字符串,用于调试目的,但不会影响 Symbol 的唯一性。
const sym1 = Symbol();
const sym2 = Symbol('description');
const sym3 = Symbol('description');
console.log(sym2 === sym3); // false
Symbol 作为对象属性
Symbol 可以作为对象的属性键,确保属性名不会与其他属性冲突。使用方括号语法将 Symbol 作为属性键。
const id = Symbol('id');
const user = {
name: 'Alice',
[id]: 123
};
console.log(user[id]); // 123
全局 Symbol 注册表
通过 Symbol.for(key) 可以在全局 Symbol 注册表中创建或获取一个 Symbol。如果 key 已存在,则返回对应的 Symbol;否则创建一个新的 Symbol 并注册。
const sym1 = Symbol.for('global');
const sym2 = Symbol.for('global');
console.log(sym1 === sym2); // true
内置 Symbol 值
JavaScript 提供了一些内置的 Symbol 值,用于实现特定的语言行为。例如:
Symbol.iterator:定义对象的默认迭代器。Symbol.toStringTag:定制对象的toString行为。
const obj = {
[Symbol.toStringTag]: 'MyObject'
};
console.log(obj.toString()); // [object MyObject]
Symbol 的不可枚举性
Symbol 属性默认不会被 for...in 循环或 Object.keys() 枚举。需要使用 Object.getOwnPropertySymbols() 获取对象的 Symbol 属性。
const obj = {
[Symbol('key')]: 'value',
name: 'Alice'
};
console.log(Object.keys(obj)); // ['name']
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(key)]
Symbol 的转换限制
Symbol 不能直接转换为字符串或数字,否则会抛出错误。必须显式调用 toString() 方法或通过 description 属性获取描述。

const sym = Symbol('desc');
console.log(sym.toString()); // Symbol(desc)
console.log(sym.description); // 'desc'
Symbol 的应用场景
- 唯一属性键:避免对象属性名冲突。
- 私有属性模拟:通过 Symbol 实现类似私有属性的效果。
- 元编程:使用内置 Symbol 值定制对象行为(如迭代、类型标签等)。
const privateKey = Symbol('private');
class MyClass {
constructor() {
this[privateKey] = 'secret';
}
getSecret() {
return this[privateKey];
}
}
const instance = new MyClass();
console.log(instance.getSecret()); // 'secret'
console.log(instance[privateKey]); // undefined (除非有 Symbol 引用)






