Symbol用处2则

  • Symbol的值是唯一的,用来解决命名冲突的问题。
  • Symbol值不能与其他类型数据进行运算。
  • Symbol定义的对象属性不能使用for...in​遍历循环,但是可以使用Reflect.ownKeys 来获取对象的所有键名
  • let s1 = Symbol();
    console.log(typeof s1); // "symbol"
    let s2 = Symbol('hello');
    let s3 = Symbol('hello');
    console.log(s2 === s3); // false

    基于以上特性,Symbol 属性类型比较适合用于两类场景中:常量值和对象属性。

  • (1)避免常量值重复

  • getValue 函数会根据传入字符串参数 key 执行对应代码逻辑:

  • function getValue(key) {
      switch(key){
        case 'A':
          ...
        case 'B':
          ...
      }
    }
    getValue('B');

    这段代码对调用者而言非常不友好,因为代码中使用了魔术字符串(Magic string,指的是在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值),导致调用 getValue 函数时需要查看函数代码才能找到参数 key 的可选值。所以可以将参数 key 的值以常量的方式声明:

  • const KEY = {
      alibaba: 'A',
      baidu: 'B',
    }
    function getValue(key) {
      switch(key){
        case KEY.alibaba:
          ...
        case KEY.baidu:
          ...
      }
    }
    getValue(KEY.baidu);

    但这样也并非完美,假设现在要在 KEY 常量中加入一个 key,根据对应的规则,很有可能会出现值重复的情况:

  • const KEY = {
      alibaba: 'A',
      baidu: 'B',
      tencent: 'B'
    }

    这就会出现问题:

  • getValue(KEY.baidu) // 等同于 getValue(KEY.tencent)

    所以在这种场景下更适合使用 Symbol,不需要关心值本身,只关心值的唯一性:

  • const KEY = {
      alibaba: Symbol(),
      baidu: Symbol(),
      tencent: Symbol()
    }

    (2)避免对象属性覆盖

  • 函数 fn 需要对传入的对象参数添加一个临时属性 user,但可能该对象参数中已经有这个属性了,如果直接赋值就会覆盖之前的值。此时就可以使用 Symbol 来避免这个问题。创建一个 Symbol 数据类型的变量,然后将该变量作为对象参数的属性进行赋值和读取,这样就能避免覆盖的情况:
  •   function fn(o) { 
        const user = Symbol()
        o[user] = 'zzz'
        console.log('======方括号获取',o[user]);
        console.log('======点获取',o.user);
      }
      fn({ user: { id: 12, name: 33 } })

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值