文章目录
为什么要在es6中引入symbol
symbol是es6中的新特性。它和null,undefined,number,Boolean,object,string一起是js的七种数据类型。
symbol用来生成独一无二的值,它解决了命名冲突的问题。使用symbol机制,就不会出现同名变量,避免了不经意中修改某些变量或者变量覆盖,提高了代码的安全性。
独一无二的值还可以用来做对象的属性。
symbol,独一无二的值
symbol只是一种数据类型,不是对象,因此,不能使用new操作符生成symbol,直接使用symbol函数就好了。
symbol最常用的就是symbol(),symbol.for(),symbol.keyfor()函数。
symbol( )
symbol函数用来初始化一个symbol变量。由于symbol是独一无二的,所以任意的symbol值都不相等。
symbol分为带描述的symbol和不带描述的symbol。不带描述的symbol如上图所示。在symbol函数中添加自己的描述,就得到了带描述的symbol。 建议使用带描述的symbol,也便于自己辨认。
== 使用symbol生成的变量不会被symbol.for搜索到,也就是说,symbol生成了变量之后,再也无法找到一个跟它相等的值。==
symbol用作不希望被外界更改的属性的属性名。
symbol.for()
通过它我们可以多次使用同一个symbol变量。
这个函数是根据描述,来返回对应的变量。如果没有在全局查找到拥有这个描述的symbol变量,就自己创建这个symbol变量。因此,不论你对同一个描述执行多少次symbol.for,最后最多只会创建一次symbol变量。
不论你再什么地方使用symbol.for,最终生成的变量都会在全局symbol变量中,都能够在其他地方搜索到。
注意symbol和symbol.for:
symbol.keyfor
它接收一个symbol变量,返回这个变量的描述符。symbol.keyfor和symbol.for可以组合使用,只有通过symbol.for定义的symbol变量才能使用symbol.keyfor方法获得描述符。
使用symbol变量作为属性名
在我看来,symbol就是为了属性名而生的。
使用symbol变量做对象的属性名时,不能使用点符号,只能使用方括号。点符号后面接的是字符串,所以后面的symbol变量会被当成一个字符串,而不是一个变量。只有使用方括号才能达到我们想要的效果。
使用symbol变量做属性名会发生什么事?
symbol变量做属性名会造成无法用for in ,for of等常规方法来获得这个属性,这就意味着,我们在普通遍历属性时会遗漏掉它们。
解决方法:
- Object.getOwnPropertySymbols()
这个函数以数组的形式返回对象中所有的symbol属性名。 - Reflect.ownKeys()
这个方法可以返回所有类型的键名,包括常规属性名和 Symbol 属性名。
使用symbol做属性名虽然遍历的时候麻烦了一点,但这也是他的好处之一:
可以利用这个特性声明非私有的内部方法