• JavaScript – Symbol


    前言

    Symbol 是 es6 的特性. 如果只是写业务逻辑代码, 其实是不太会用到的. 如果是做架构, 封装, UI 组件才有需要.

    但学它的概念是好的. es6 有需要内置的 Symbol 链接者许多常用的功能, 如果想修改这些 build-in 的东西, 了解 Symbol 是必须的.

    参考

    阮一峰 – Symbol

    没有钱买阮老师的书支持, 在这里帮忙推荐一下, 想学 JavaScript 新手, 或新手进阶都很适合读.

    Unique String

    调用 Symbol 方法, 传入一个 name 或者叫 description 就会返回一个 Symbol (不需要 new 哦)

    const mySymbol1 = Symbol('name');
    const mySymbol2 = Symbol('name');
    console.log(mySymbol1 === mySymbol2); // false

    Symbol 的特色是它即使用同一个 name 创建出来, 但 Symbol 却是不同的.

    有时候写代码时, 我们会用一些特别字符串 (hardcode) 做判断. 这样不太好, 因为不可以 rename 全场换. 把它装入到 Symbol 就剪掉了这种耦合关系.

    Symbol Description

    const mySymbol1 = Symbol('name');
    console.log(mySymbol1.description === 'name'); // true

    通过 description 可以拿回初始化时传入的 name

    Symbol in Object

    其实这个才是重点. Symbol 可以作为 object 的 key.

    const mySymbol1 = Symbol('name');
    const obj = {
      name: 'Derrick',
      [mySymbol1]: 'value',
    };
    console.log(obj[mySymbol1] === 'value'); // value
    console.log(Object.keys(obj)); // ['name']
    console.log(Object.getOwnPropertySymbols(obj)); // [mySymbol1]
    console.log(Reflect.ownKeys(obj)); // ['name', mySymbol1]

    注意, 获取 symbol key 的方式, 我们常用的 Object.keys 是遍历不到 Symbol 的.

    为什么说这个才是重点呢? 因为 es6 用了许多 build-in 的 Symbol 在各种 object 上.

    实现了许多方法. 比如最有名的 Symbol.iterator. 总共有 11 种 build-in Symbol.

    从这里就可以明白, 为什么 Symbol 是 unique 的, 因为它需要放到 object key 里头, 用 string 会撞名字.

    此外因为有这些 build-in Symbol, 所以 Object.keys 默认遍历不出来.

    Symbol 的 best practice 就是像那么 build-in 的 Symbol 那样使用. 下面介绍几个比较火的.

    Build-in Symbol

    Symbol.hasInstance

    class MyClass {
      [Symbol.hasInstance](foo) {
        return foo instanceof Array;
      }
    }
    
    [1, 2, 3] instanceof new MyClass() // true

    看明白了吗, instanceof 其实是调用了对象里面 Symbol.hasInstance 的方法.

    Symbol.Split

    const array = 'abc'.split({
      [Symbol.split](value) {
        console.log(value === 'abc'); // true
        return ['a', 'b', 'c'];
      },
    });
    
    console.log(array); // ['a', 'b', 'c']

    string 的 split 方法, 参数 seperator 除了可以是 string | Regex 以外还可以是一个带有 Symbol.split 的对象.

    Symbol.iterator

    任何对象, 一旦有了 Symbol.iterator 就变成了迭代器. 可以被 for of 遍历.

    const myIterable = {};
    myIterable[Symbol.iterator] = function* () {
      yield 1;
      yield 2;
      yield 3;
    };
    
    [...myIterable] // [1, 2, 3]

    Symbol.toPrimitive

    控制当对象被类型转换时的逻辑

    let obj = {
      [Symbol.toPrimitive](hint) {
        switch (hint) {
          case 'number':
            return 123;
          case 'string':
            return 'str';
          case 'default':
            return 'default';
          default:
            throw new Error();
         }
       }
    };
    
    2 * obj // 246
    3 + obj // '3default'
    obj == 'default' // true
    String(obj) // 'str'

    hint = number 意思是, 对象要被转去 number 了, 这时就应该返回一个数字. 

    default 的意思是可能是转成 number, 也可能是 string. (这个比较难理解)

    据这个例子主要是让你体会一下 Symbol 搭配 object 和各种操作场景下, 它是如果运作的. 

    总结

    Symbol 主要的玩法就像诸多 build-in Symbol 那样. 操作语法 + 对象 Symbol = resul

  • 相关阅读:
    软件测试描述错误
    软件测试homework2
    第九次
    第七次作业
    第六次作业
    第五次作业
    第四次作业
    第三次
    软件测试Lab2 Selenium及自动化测试
    软件测试(四)主路径覆盖hw3
  • 原文地址:https://www.cnblogs.com/keatkeat/p/16253717.html
Copyright © 2020-2023  润新知