先来看看Symbol函数的定义:1
Symbol(description?) → symbol
接收一个描述(描述可以为undefined),返回一个symbol类型的变量。
然后有意思的来了,首先传进去的参数只是个描述,给读代码的人看的,和返回值无关,Symbol函数每次都返回一个不一样的symbol类型变量,像这样:1
2
3
4
5
6
7
8
9> Symbol() === Symbol()
false
> Symbol("a") === Symbol("a")
false
> let a = Symbol("this is a")
> a === a
true
不过要注意的是,symbol类型虽然是一个基本类型,但是一般来说不被json格式支持,不要试图在json格式里使用它,像这样([k]的含义是用k的内容作为对象键-值对的键而不是用k这个字符串作为键):1
2
3
4> let k = Symbol("key")
> let obj = {[k]: 5}
> JSON.stringify(obj)
{}
这导致了nodejs的REPL打印对象的时候会漏掉以symbole作为键的内容,像这样:1
2
3
4> let k = Symbol("key")
> let obj = {[k]: 5, d: 6}
> obj
{ d: 6 }
不过直接访问是没有问题的:1
2
3
4> let k = Symbol("key")
> let obj = {[k]: 5, d: 6}
> obj[k]
5
所以Symbol最大的用处是用来做常量定义,相比:1
const ERROR = "error"
使用Symbol1
const ERROR = Symbol("error")
会更好一些,比如你有两个包log和print,它们的ERROR常量其实不是一回事,用Symbol就会很清晰:1
2> log.ERROR === print.ERROR
false