• ES6中的Symbol


    ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。

    重要的干货提前说:当使用JSON.stringify()将对象转换成JSON字符串的时候,Symbol属性也会被排除在输出内容之外,所以JSON.parse(JSON.stringify(oldObj))不能拷贝含有Symbol属性的对象。另一文:JSON.parse拷贝的局限性

    它是 JavaScript 语言的第七种数据类型,前六种是:undefinednull、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)

    这样写是会报错的:
    let a = new Symbol()
    
    Uncaught TypeError: Symbol is not a constructor
    注意:Symbol函数前不能使用new命令,否则会报错。这是因为生成的 Symbol 是一个原始类型的值,不是对象。
    所以,我们只要将Symbol当成唯一的字符串就行
    正确写法: let s
    = Symbol(); typeof s // "symbol"

    1,概要:

      1,每一个Symbol都不相等

    // 没有参数的情况
    let s1 = Symbol();
    let s2 = Symbol();
    
    s1 === s2 // false

      2,Symbol能接受一个参数,注意数只是表示对当前 Symbol 值的描述,相同参数的Symbol值也都是不相同的

        参数可以为所有类型,如果 Symbol 的参数是一个对象,就会调用该对象的toString方法

      3,注意:Symbol 值不能与其他类型的值进行运算,但是,Symbol 值可以显式转为字符串,另外,Symbol 值也可以转为布尔值,但是不能转为数值。

        

    let sym = Symbol('My symbol');
    String(sym) // 'Symbol(My symbol)'
    
    let sym = Symbol();
    Boolean(sym) // true
    
    Number(sym) // TypeError
    
    "your symbol is " + sym
    // TypeError: can't convert symbol to string

    2,Symbol.prototype.description

    let sym = Symbol('hello')
    sym //Symbol(hello)
    sym.description //"hello"

    3,作为属性名时的遍历

    Symbol 作为属性名,遍历对象的时候,该属性不会出现在for...infor...of循环中,也不会被Object.keys()Object.getOwnPropertyNames()JSON.stringify()返回。

    但是,它也不是私有属性,有一个Object.getOwnPropertySymbols()方法,可以获取指定对象的所有 Symbol 属性名。该方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。

    const obj = {};
    let a = Symbol('a');
    let b = Symbol('b');
    
    obj[a] = 'Hello';
    obj[b] = 'World';
    for (let i in obj) {
      console.log(i); // 无输出
    }
    const objectSymbols = Object.getOwnPropertySymbols(obj); objectSymbols // [Symbol(a), Symbol(b)]

    另一个新的 API,Reflect.ownKeys()方法可以返回所有类型的键名,包括常规键名和 Symbol 键名。

    let obj = {
      [Symbol('my_key')]: 1,
      enum: 2,
      nonEnum: 3
    };
    
    Reflect.ownKeys(obj)
    //  ["enum", "nonEnum", Symbol(my_key)]

    4,Symbol.for(),Symbol.keyFor() 

    Symbol.for()Symbol()这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会

    let s1 = Symbol.for('foo');
    let s2 = Symbol.for('foo');
    s1 === s2 // true
    
    Symbol.for("bar") === Symbol.for("bar")
    // true
    Symbol("bar") === Symbol("bar")
    // false
    
    
    Symbol.keyFor()方法返回一个已登记的 Symbol 类型值的key。
    let s1 = Symbol.for("foo");
    Symbol.keyFor(s1) // "foo"
    
    let s2 = Symbol("foo");
    Symbol.keyFor(s2) // undefined

    Symbol.for()的这个全局登记特性,可以用在不同的 iframe 或 service worker 中取到同一个值。

    iframe = document.createElement('iframe');
    iframe.src = String(window.location);
    document.body.appendChild(iframe);
    
    iframe.contentWindow.Symbol.for('foo') === Symbol.for('foo')
    // true

     

  • 相关阅读:
    【Nginx】ngx_event_core_module模块
    ELMAH--Using HTTP Modules and Handlers to Create Pluggable ASP.NET Components 77 out of 90 rated th
    nyist oj 214 单调递增子序列(二) (动态规划经典)
    java 入门书籍(java7)
    ARCGIS将WGS84坐标投影到高斯平面
    【linux】linux下对java程序生成dump文件,并使用IBM Heap Analyzer进行分析,查找定位内存泄漏的问题代码
    【springboot】【socket】spring boot整合socket,实现服务器端两种消息推送
    【linux】linux修改open file 大小
    【docker】docker限制日志文件大小的方法+查看日志文件的方法
    【docker】docker部署spring boot服务,但是docker logs查看容器输出控制台日志,没有日志打印,日志未打印,docker logs不打印容器日志
  • 原文地址:https://www.cnblogs.com/hsmWorld/p/12802489.html
Copyright © 2020-2023  润新知