![React工程师修炼指南](https://wfqqreader-1252317822.image.myqcloud.com/cover/475/37323475/b_37323475.jpg)
上QQ阅读APP看书,第一时间看更新
1.4 Symbol
ES5中提供的6种数据类型分别是:Undefined、Null、布尔值(Boolean)、字符串(String)、数值(Number)和对象(Object)。ES6中新增一种数据类型Symbol来表示唯一的值。每一个创建的symbol都是唯一的,这样在实际运用中可以创建一些唯一的属性及定义私有变量。symbol的创建如下:
![](https://epubservercos.yuewen.com/D960D7/19773741008833706/epubprivate/OEBPS/Images/25_03.jpg?sign=1739218764-CvGprs220s2UxK7LkH9PvlOgwbT3KYN5-0-ac4d5fcfd74fb2e8086ebc48df7d9b26)
上述创建symbol后,调用时需要注意不像其他类型数据创建时需要加“new”运算符实例化,这里symbol都是直接调用函数。每个symbol都是独一无二的,类型是Symbol,代码如下:
![](https://epubservercos.yuewen.com/D960D7/19773741008833706/epubprivate/OEBPS/Images/25_04.jpg?sign=1739218764-1RsefEABzx48vUTfyLI4pKvp7UJP89K5-0-df0848f78c91648e321e440863ecabf0)
![](https://epubservercos.yuewen.com/D960D7/19773741008833706/epubprivate/OEBPS/Images/26_01.jpg?sign=1739218764-qZdcCmc1GNwASSG4IAMhsjtA9XapuIjP-0-de9432c3edebca4eecb188412442e501)
上述代码中,即使Symbol传入的字符串是一样的,但是最终s1和s2还是有区别的,这也验证了symbol的唯一性。目前前端项目都会采用模块化构建,为了防止对象属性名被覆盖,可以通过symbol来定义属性名。在symbol出来之前会直接定义对象属性名如下:
![](https://epubservercos.yuewen.com/D960D7/19773741008833706/epubprivate/OEBPS/Images/26_02.jpg?sign=1739218764-jbvYl2kSFgMcuJKFnGEDiO89lQhcupVN-0-51c5baed40e69a8ab8aae16298339555)
上述代码在引用过程中可能会在追加属性的时候造成属性覆盖的情况,如:
![](https://epubservercos.yuewen.com/D960D7/19773741008833706/epubprivate/OEBPS/Images/26_03.jpg?sign=1739218764-RAp4b50GmqQ5h8lzbaQrbF5sjSdBpDSz-0-a330d9bf8a2ec5221a100d8e679e4b14)
为了防止变量覆盖的情况,可以通过symbol来定义对象属性名,防止对象属性被覆盖:
![](https://epubservercos.yuewen.com/D960D7/19773741008833706/epubprivate/OEBPS/Images/26_04.jpg?sign=1739218764-8MpdpEczXnDNkyHPQT00bR8Y03ZTWqnD-0-f0b0922439a039d00118d5d89ffaa6ef)
这里也是利用symbol类型值唯一性的特征使得对象中属性不会被覆盖。利用symbol作为属性名,属性名不会被Object.keys()、Object.getOwnPropertyNames()、for……in循环或者返回。代码如下:
![](https://epubservercos.yuewen.com/D960D7/19773741008833706/epubprivate/OEBPS/Images/26_05.jpg?sign=1739218764-jkHJys6mHxXROAmsmbtGCt0ihCwy5qKx-0-e1332a8dccc820f0c74e175fed1b32e7)
![](https://epubservercos.yuewen.com/D960D7/19773741008833706/epubprivate/OEBPS/Images/27_01.jpg?sign=1739218764-sdhI2uRBve1bOct89TM3S5kKwkeVu4Th-0-99af4ee0fb4ba93432d1d78795f7a434)
symbol属性并不是私有属性,如果要获取属性名的symbol属性可以通过Object.getOwnPropertySymbols()获取对象的所有symbol属性,同样也可以通过Reflect.ownKeys()反射api来获取属性,代码如下:
![](https://epubservercos.yuewen.com/D960D7/19773741008833706/epubprivate/OEBPS/Images/27_02.jpg?sign=1739218764-R3S7JCau68pqS21IITE6NOWMX7pZxbTl-0-3310ad9be3d16c7d44d4ce6d1c805e66)
同样可以在“类”里利用symbol来定义私有属性及方法,例如:
![](https://epubservercos.yuewen.com/D960D7/19773741008833706/epubprivate/OEBPS/Images/27_03.jpg?sign=1739218764-nIBxu2uHNwOX4UTNBILU6Dq5Wxm1CUby-0-01f03907f2e0b2dbfec5ae7207ba19de)