js实现symbol
Symbol 的基本概念
Symbol 是 ECMAScript 6 引入的一种新的原始数据类型,表示独一无二的值。Symbol 值通过 Symbol() 函数生成,每个 Symbol 值都是唯一的,即使传入相同的描述符。
const sym1 = Symbol('foo');
const sym2 = Symbol('foo');
console.log(sym1 === sym2); // false
创建 Symbol
使用 Symbol() 函数创建 Symbol 值,可以传入一个可选的字符串作为描述符,主要用于调试。
const sym = Symbol('description');
console.log(sym); // Symbol(description)
Symbol 作为对象属性
Symbol 值可以作为对象的属性名,避免属性名冲突。使用方括号语法定义和访问 Symbol 属性。

const obj = {};
const sym = Symbol('key');
obj[sym] = 'value';
console.log(obj[sym]); // value
遍历 Symbol 属性
Symbol 属性不会出现在 for...in、Object.keys() 或 Object.getOwnPropertyNames() 中。需要使用 Object.getOwnPropertySymbols() 获取对象的 Symbol 属性。
const obj = {};
const sym = Symbol('key');
obj[sym] = 'value';
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(key)]
全局 Symbol 注册表
通过 Symbol.for() 可以在全局 Symbol 注册表中创建或重用 Symbol。传入相同的键会返回相同的 Symbol 值。

const sym1 = Symbol.for('foo');
const sym2 = Symbol.for('foo');
console.log(sym1 === sym2); // true
使用 Symbol.keyFor() 可以获取全局 Symbol 的描述符。
const sym = Symbol.for('foo');
console.log(Symbol.keyFor(sym)); // foo
内置 Symbol 值
JavaScript 提供了一些内置的 Symbol 值,用于控制对象的某些行为。例如:
Symbol.iterator: 定义对象的默认迭代器。Symbol.toStringTag: 定义对象的toString行为。
const obj = {
[Symbol.toStringTag]: 'MyObject'
};
console.log(obj.toString()); // [object MyObject]
Symbol 的应用场景
- 避免属性名冲突:在扩展对象时,使用 Symbol 可以避免覆盖已有属性。
- 定义私有属性:Symbol 属性不会被常规方法遍历,可以模拟私有属性。
- 实现协议:通过内置 Symbol 值实现自定义行为,如迭代协议。
class MyClass {
constructor() {
this[Symbol('private')] = 'secret';
}
}
const instance = new MyClass();
console.log(Object.getOwnPropertySymbols(instance)); // [Symbol(private)]






