Symbol
是一个原始数据类型
,类似于String、Number、Boolean、Null、undefined,主要用途是创建对象的唯一属性键
,有助于避免命名冲突和保护私有属性。
创建Symbol
Symbol
类型通过Symbol()
构造函数创建,可以接受一个可选的描述字符串
,但该字符串仅用于调试目的,不会影响Symbol的唯一性。
const s1 = Symbol()
const s2 = Symbol('description')
console.log(s1) // Symbol()
console.log(s2) // Symbol(description)
即使两个调用Symbol()构造函数时传入相同的描述字符串,得到的Symbol也是不同的:
const s1 = Symbol('foo')
const s2 = Symbol('foo')
console.log(s1 === s2) // false
Symbol的特性
唯一性
:每个Symbol都是唯一的,即使它们的描述相同。不可枚举
:当使用for...in
循环或Object.keys()
、Object.getOwnPropertyNames()
等方法时,Symbol类型的属性不会被列举出来。隐私性
:Symbol可以用来创建私有属性,因为它们不会像普通字符串那样容易被外部代码访问到。
内置的Symbol
除了自定义的Symbol外,ES6还定义了一些内置的Symbol,被用来实现语言的某些特性,比如Symbol.iterator
用于实现迭代器模式。
const obj = {
[Symbol.iterator] () {
let count = 0
return {
next: () => ({ value: count++, done: count > 10 })
}
}
}
for (let x of obj) {
console.log(x)
}
Symbol作为对象的属性键
Symbol
常被用作对象的属性键,以创建私有或隐藏的属性。
const myObj = {}
const mySymbol = Symbol('gary key')
myObj[mySymbol] = 'gary value'
console.log(myObj) // 输出对象时,Symbol类型的属性不会显示
console.log(Object.keys(myObj)) // []
console.log(Object.getOwnPropertySymbols(myObj)) // [Symbol(gary key)]
注意事项
- 不要随意将
Symbol
类型的属性暴露给外部代码,这可能会破坏Symbol的隐私性。 - 虽然Symbol可以作为属性键,但不能作为数组的索引。
总的来说,Symbol在JavaScript中提供了创建唯一标识符的能力,这对于构建复杂的程序结构和避免命名冲突非常有用。