Symbol 是什么?
Symbol
是 ES6 引入的一种新的数据类型,它的作用是用来生成唯一的标识符。每个 Symbol
都是独一无二的,即使你创建的 Symbol
描述相同,它们也不会相等。
怎么创建 Symbol?
创建 Symbol
很简单,直接调用 Symbol()
函数就行。你可以给它传个描述,主要是为了调试时看得清楚,但这并不会影响它的唯一性。
const sym1 = Symbol('desc'); // 有描述
const sym2 = Symbol('desc'); // 还是不同的实例
Symbol 有什么特点?
-
唯一性:每个
Symbol
都是唯一的,不能和其他Symbol
比较相等。const sym1 = Symbol('id'); const sym2 = Symbol('id'); console.log(sym1 === sym2); // false
-
不可变性:一旦创建,
Symbol
就不能修改,没法像字符串那样变来变去。 -
不能自动转换成字符串:如果你想把
Symbol
打印出来,必须调用.toString()
方法。const sym = Symbol('hello'); console.log(sym.toString()); // "Symbol(hello)"
Symbol 的用途
-
避免属性冲突:在大型项目中,不同模块可能会用到相同的属性名。用
Symbol
作为属性名,就能确保它们唯一,不会被覆盖。const uniqueKey = Symbol('unique'); const obj = { [uniqueKey]: 'value' }; console.log(obj[uniqueKey]); // 'value'
-
模拟私有属性:JavaScript 对象的属性是公开的,没法像传统 OOP 那样定义私有属性。使用
Symbol
,你可以模拟私有属性,这样外部无法直接访问。const privateKey = Symbol('private'); const obj = { [privateKey]: 'This is private' }; console.log(obj[privateKey]); // 'This is private'
-
实现迭代器:如果你需要自定义对象的迭代行为,可以通过
Symbol.iterator
来实现。const myIterable = { [Symbol.iterator]: function() { let i = 0; const data = ['a', 'b', 'c']; return { next: function() { if (i < data.length) { return { value: data[i++], done: false }; } else { return { done: true }; } } }; } }; for (const item of myIterable) { console.log(item); // a, b, c }
-
全局唯一的标识符:如果你想在整个应用中共享一个唯一标识符,可以使用
Symbol.for()
,它会在全局注册这个Symbol
。const sym1 = Symbol.for('shared'); const sym2 = Symbol.for('shared'); console.log(sym1 === sym2); // true
常见方法
Symbol.for()
:查找全局注册的Symbol
,如果没有找到就创建一个新的。Symbol.keyFor()
:获取已经注册的全局Symbol
的描述。Object.getOwnPropertySymbols()
:获取对象的符号属性(仅限对象本身的,不包括继承的)。Reflect.ownKeys()
:获取对象的所有键,包括符号键和普通键。
总结
Symbol
的核心作用就是生成独一无二的标识符,它避免了属性名冲突、模拟私有属性、实现特殊功能等多种用途。如果你需要在一个复杂的应用中确保标识符的唯一性,或者想要定义私有属性,Symbol
就是一个很有用的工具。