JS Symbol 数据类型
作用
它是 JavaScript 语言的第七种数据类型,表示独一无二
let s = Symbol()
typeof s
// "symbol"
可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。
let s1 = Symbol('foo')
let s2 = Symbol('bar')
s1 // Symbol(foo)
s2 // Symbol(bar)
s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(bar)"
因为独一无二,所以不相等
// 没有参数的情况
let s1 = Symbol()
let s2 = Symbol()
s1 === s2 // false
// 有参数的情况
let s1 = Symbol('foo')
let s2 = Symbol('foo')
s1 === s2 // false
不能与其他类型的值进行运算
let sym = Symbol('My symbol')
"your symbol is " + sym
//VM514:1 Uncaught TypeError: Cannot convert a Symbol value to a string
可以显式转为字符串
let sym = Symbol('My symbol')
String(sym) // 'Symbol(My symbol)'
sym.toString() // 'Symbol(My symbol)'
也可以转为布尔值,但是不能转为数值
let sym = Symbol()
Boolean(sym) // true
!sym // false
if (sym) {
// ...
}
Number(sym) // TypeError
sym + 2 // TypeError
Symbol.prototype.description
返回 Symbol 值得描述
const sym = Symbol('foo')
sym.description // "foo"
//当然这种方式也可以
const sym = Symbol('foo')
sym.toString() // "Symbol(foo)"
作为属性名的 Symbol
let mySymbol = Symbol()
// 第一种写法
let a = {}
a[mySymbol] = 'Hello!'
// 第二种写法
let a = {
[mySymbol]: 'Hello!'
}
// 第三种写法
let a = {}
Object.defineProperty(a, mySymbol, { value: 'Hello!' })
// 以上写法都得到同样结果
a[mySymbol] // "Hello!"
Symbol 值作为对象属性名时,不能用点运算符,因为点运算符后面总是字符串
const mySymbol = Symbol()
const a = {}
a.mySymbol = 'Hello!'
a[mySymbol] // undefined
a['mySymbol'] // "Hello!"
同理,在对象的内部,使用 Symbol 值定义属性时,Symbol 值必须放在方括号之中。
let obj = {
[s](arg) { ... }
}
Object.getOwnPropertySymbols()
返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。
Symbol 作为属性名,该属性不会出现在 for...in、for...of 循环中,也不会被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify() 返回。但是,它也不是私有属性
const obj = {}
let a = Symbol('a')
let b = Symbol('b')
obj[a] = 'Hello'
obj[b] = 'World'
const objectSymbols = Object.getOwnPropertySymbols(obj)
objectSymbols
// [Symbol(a), Symbol(b)]
由于以 Symbol 值作为名称的属性,不会被常规方法遍历得到。我们可以利用这个特性,为对象定义一些非私有的、但又希望只用于内部的方法。
Symbol.for()
Symbol.for() 与 Symbol() 这两种写法,都会生成新的 Symbol
它们的区别是,前者会被登记在全局环境中供搜索,后者不会。
Symbol.for() 不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的 key 是否已经存在,如果不存在才会新建一个值。
比如,如果你调用 Symbol.for("cat")30 次,每次都会返回同一个 Symbol 值,但是调用 Symbol("cat")30 次,会返回 30 个不同的 Symbol 值。
Symbol.for("bar") === Symbol.for("bar")
// true
Symbol("bar") === Symbol("bar")
// false
Symbol.keyFor()
返回一个已登记的 Symbol 类型值的 key
let s1 = Symbol.for("foo")
Symbol.keyFor(s1) // "foo"
let s2 = Symbol("foo")
Symbol.keyFor(s2) // undefined
Symbol.for 为 Symbol 值登记的名字,是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值。
iframe = document.createElement('iframe')
iframe.src = String(window.location)
document.body.appendChild(iframe)
iframe.contentWindow.Symbol.for('foo') === Symbol.for('foo')
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
下一篇: TypeScript 常见问题
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论