符号是es6新增的一个数据类型,它通过使用函数Symbol(符号描述)来创建

  1. const s = Symbol('这是符号描述')

符号设计的初衷是为啦给对象设置私有属性

私有属性

只能在对象内部访问,外面无法访问

  1. const s = Symbol('sd')
  2. const obj = {
  3. a: 1,
  4. b: 2,
  5. [s]: 123,
  6. }

在其控制台显示为
image.png
从图中可以看出 【s】的属性名被替换啦,没有正确的属性名就无法获取到此属性值,虽然在其控制台中显示啦属性值但是你无法获取到,但是他定义在全局可以凭借obj[s]访问到,需要包裹在立即执行函数内

  1. const obj = (() => {
  2. const s = Symbol('sd')
  3. return {
  4. a: 1,
  5. b: 2,
  6. [s]: 123,
  7. }
  8. })()

符号具有以下特点

1:没有字面量

  1. const s = Symbol('sd')
  2. const a = 'asdfsdaf'
  3. console.log(s)
  4. console.log(a)

image.png

2:使用 typeof 得到的类型是 symbol

image.png

3:每次调用 Symbol 函数得到的符号永远不相等,无论符号名是否相同

  1. const s = Symbol('sd')
  2. const a = Symbol('sd')
  3. console.log(s === a)

image.png

4:符号可以作为对象的属性名存在,这种属性称之为符号属性

开发者可以通过精心的设计,让这些属性无法通过常规方式被外界访问

符号属性是不能枚举的,因此在 for-in 循环中无法读取到符号属性,Object.keys 方法也无法读取到符号属性

Object.getOwnPropertyNames 尽管可以得到所有无法枚举的属性,但是仍然无法读取到符号属性

  1. const s = Symbol('sd')
  2. const obj = {
  3. a: 1,
  4. b: 2,
  5. [s]: 123,
  6. [s](){
  7. console.log('asd')
  8. }
  9. }
  10. for (const prop in obj) {
  11. console.log(prop)
  12. }

image.png

ES6 新增 Object.getOwnPropertySymbols 方法,可以读取符号

image.png
示例

  1. const Hero = (() => {
  2. const getRandom = Symbol();
  3. return class {
  4. constructor(attack, hp, defence) {
  5. this.attack = attack;
  6. this.hp = hp;
  7. this.defence = defence;
  8. }
  9. gongji() {
  10. //伤害:攻击力*随机数(0.8~1.1)
  11. const dmg = this.attack * this[getRandom](0.8, 1.1);
  12. console.log(dmg);
  13. }
  14. [getRandom](min, max) { //根据最小值和最大值产生一个随机数
  15. return Math.random() * (max - min) + min;
  16. }
  17. }
  18. })();
  19. const h = new Hero(3, 6, 3);
  20. const sybs = Object.getOwnPropertySymbols(Hero.prototype);
  21. const prop = sybs[0];
  22. console.log(h[prop](3, 5))
  23. </script>

5:符号无法被隐式转换,因此不能被用于数学运算、字符串拼接或其他隐式转换的场景,但符号可以显式的转换为字符串,通过 String 构造函数进行转换即可,console.log 之所以可以输出符号,是它在内部进行了显式转换


示例

  1. //对象的使用方式
  2. // const hero = (function () {
  3. // const getRandom = Symbol();
  4. // return {
  5. // attack: 30,
  6. // hp: 300,
  7. // defence: 10,
  8. // gongji() { //攻击
  9. // //伤害:攻击力*随机数(0.8~1.1)
  10. // const dmg = this.attack * this[getRandom](0.8, 1.1);
  11. // console.log(dmg);
  12. // },
  13. // [getRandom](min, max) { //根据最小值和最大值产生一个随机数
  14. // return Math.random() * (max - min) + min;
  15. // }
  16. // }
  17. // })()
  18. // console.log(hero);
  19. //类的使用方式
  20. const Hero = (() => {
  21. const getRandom = Symbol();
  22. return class {
  23. constructor(attack, hp, defence) {
  24. this.attack = attack;
  25. this.hp = hp;
  26. this.defence = defence;
  27. }
  28. gongji() {
  29. //伤害:攻击力*随机数(0.8~1.1)
  30. const dmg = this.attack * this[getRandom](0.8, 1.1);
  31. console.log(dmg);
  32. }
  33. [getRandom](min, max) { //根据最小值和最大值产生一个随机数
  34. return Math.random() * (max - min) + min;
  35. }
  36. }
  37. })();
  38. const h = new Hero(3, 6, 3);
  39. console.log(h);