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 就是一个很有用的工具。