zoukankan      html  css  js  c++  java
  • 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

     

  • 相关阅读:
    WPA/WPA2无法暴力破解
    被书本知识所边缘化的软件工程师
    栈和队列
    Oracle update 之部分更新
    SAAS之初体验
    Entity Framework
    ResourceWriter和ResxResourceWriter的區別
    C#中將顏色轉換成網頁16進制顏色代碼
    Javascript功能代码收集(不断更新中...)
    .net1.1转换成更高版本的问题总结
  • 原文地址:https://www.cnblogs.com/hsmWorld/p/12802489.html
Copyright © 2011-2022 走看看