• ES6 入门教程 13 Symbol 13.2 Symbol.prototype.description & 13.3 作为属性名的 Symbol


    ES6 入门教程

    ECMAScript 6 入门

    作者:阮一峰

    本文仅用于学习记录,不存在任何商业用途,如侵删

    13 Symbol

    13.2 Symbol.prototype.description

    Symbol()函数创建 Symbol 值时,可以用参数添加一个描述。

    const sym = Symbol('foo');
    
    • 1

    上面代码中,sym这个值的描述就是字符串foo

    但是,读取这个描述需要将 Symbol 显式转为字符串,即下面的写法。

    const sym = Symbol('foo');
    
    String(sym) // "Symbol(foo)"
    sym.toString() // "Symbol(foo)"
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    上面的用法不是很方便。

    ES2019 提供了一个 Symbol 值的实例属性description,直接返回 Symbol 值的描述。

    const sym = Symbol('foo');
    
    sym.description // "foo"
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    13.3 作为属性名的 Symbol

    由于每一个 Symbol 值都是不相等的,这意味着只要 Symbol 值作为标识符,用于对象的属性名,就能保证不会出现同名的属性。

    这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。

    let mySymbol = Symbol();
    
    // 第一种写法
    let a = {};
    a[mySymbol] = 'Hello!';
    
    // 第二种写法
    let a = {
      [mySymbol]: 'Hello!'
    };
    
    // 第三种写法
    let a = {};
    Object.defineProperty(a, mySymbol, { value: 'Hello!' });
    
    // 以上写法都得到同样结果
    a[mySymbol] // "Hello!"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    上面代码通过方括号结构和Object.defineProperty()方法,将对象的属性名指定为一个 Symbol 值。

    注意,Symbol 值作为对象属性名时,不能用点运算符。

    const mySymbol = Symbol();
    const a = {};
    
    a.mySymbol = 'Hello!';
    a[mySymbol] // undefined
    a['mySymbol'] // "Hello!"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    上面代码中,因为点运算符后面总是字符串,所以不会读取mySymbol作为标识名所指代的那个值,导致a的属性名实际上是一个字符串,而不是一个 Symbol 值。

    同理,在对象的内部,使用 Symbol 值定义属性时,Symbol 值必须放在方括号之中。

    let s = Symbol();
    
    let obj = {
      [s]: function (arg) { ... }
    };
    
    obj[s](123);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    上面代码中,如果s不放在方括号中,该属性的键名就是字符串s,而不是s所代表的那个 Symbol 值。

    采用增强的对象写法,上面代码的obj对象可以写得更简洁一些。

    let obj = {
      [s](arg) { ... }
    };
    
    • 1
    • 2
    • 3

    Symbol 类型还可以用于定义一组常量,保证这组常量的值都是不相等的。

    const log = {};
    
    log.levels = {
      DEBUG: Symbol('debug'),
      INFO: Symbol('info'),
      WARN: Symbol('warn')
    };
    console.log(log.levels.DEBUG, 'debug message');
    console.log(log.levels.INFO, 'info message');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    下面是另外一个例子。

    const COLOR_RED    = Symbol();
    const COLOR_GREEN  = Symbol();
    
    function getComplement(color) {
      switch (color) {
        case COLOR_RED:
          return COLOR_GREEN;
        case COLOR_GREEN:
          return COLOR_RED;
        default:
          throw new Error('Undefined color');
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    常量使用 Symbol 值最大的好处,就是其他任何值都不可能有相同的值了,因此可以保证上面的switch语句会按设计的方式工作。

    还有一点需要注意,Symbol 值作为属性名时,该属性还是公开属性,不是私有属性。

  • 相关阅读:
    宠物经济大热,品牌应如何巧借东风搭上这趟营销顺风车呢?
    vue3 基于el-tree增加、删除节点(非TypeScript 写法)
    分享:使用宝塔搭建属于自己的邮局系统
    Java Kafka消费者组位移重设深度解析与实践
    redis学习笔记(一)--redis的认识和使用
    【爬虫】7.4. 字体反爬案例分析与爬取实战
    python系统学习笔记(基础语法大纲版)
    测试开发——项目
    LEADTOOLS 入门教程: 配置和运行文档服务 - .NET Core
    把二叉搜索树转换为累加树
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/127915180