zoukankan      html  css  js  c++  java
  • Symbol

    何为Symbol

    ES5中对象的属性名都是字符串,容易造成属性名的冲突。也就是说,当我们在调用别人的对象的同时,又想为这个对象添加一个新的方法,这个新的方法名字就容易与原对象中已有的方法名冲突。ES6引入Symbol,就是为了解决这样的问题。
    Symbol是ES6新添加的一个基本数据类型。所以在ES6中一共有七种数据类型:undefined、null、Bollean、String、Number、Object以及Symbol.

    创建Symbol

    Symbol值通过Symbol函数生成。注意,Symbol前面不能使用new 运算符,否则会报错。这是因为Symbol是一种原始数据类型,不是对象

    let s = Symbol();
    typeof s;   // "symbol"
    

    Symbol函数可以接受字符串作为参数,这主要便于在控制显示,或者转为字符串时,方便区分。如:

    var s1 = Symbol('foo');
    var s2 = Symbol('bar');
    
    s1 // Symbol(foo)
    s2 // Symbol(bar)
    
    s1.toString() // "Symbol(foo)"
    s2.toString() // "Symbol(bar)"
    

    注意: Symbol的参数仅用于对当前Symbol值的描述,并无其他实际意义。相同参数Symbol函数的返回值是不一样的。

    var s1 = Symbol();
    var s2 = Symbol();
    s1 === s2;      // false
    
    var s1 = Symbol('foo');
    var s2 = Symbol('foo');
    s1 === s2;      // false
    

    Symbol值不可与其他类型的值进行运算。

    var sym = Symbol('My symbol');
    "your symbol is " + sym
    // TypeError: can't convert symbol to string
    `your symbol is ${sym}`
    // TypeError: can't convert symbol to string
    

    但是,Symbol值可以显示为字符串。

    var sym = Symbol('My symbol');
    String(sym) // 'Symbol(My symbol)'
    sym.toString() // 'Symbol(My symbol)'
    

    作为属性名的Symbol

    Symbol值作为对象的属性名,有以下三种写法:

    var mySymbol = Symbol();
    
    // 第一种写法
    var a = {};
    a[mySymbol] = 'Hello!';
    
    // 第二种写法  在对象内部使用Symbol值定义属性,Symbol值必须放在方括号中。
    var a = {
        [mySymbol]: 'Hello!'
    };
    
    // 第三种学法
    var a = {};
    Object.defineProperty(a, mySymbol, {value: 'Hello!'});
    

    注意:Symbol值作为对象属性名时,不能用点运算符。因为点运算符后面总是字符串。

    属性名的遍历 Object.getOwnPropertySymbols()

    Object.getOwnPropertySymbols 返回的是一个数组,数组成员是作为当前对象的属性名的Symbol值。

    var obj = {};
    var a = Symbol('a');
    var b = Symbol('b');
    obj[a] = 'Hello';
    obj[b] = 'World';
    var objectSymbols = Object.getOwnPropertySymbols(obj);
    console.log(objectSymbols);     // [Symbol(a), Symbol(b)]
    

    注意:Symbol 作为属性名,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。
    Reflact.ownKeys()可以返回所有类型的键名,包括常规键名和Symbol键名。

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

    Symbol.for() Symbol.keyFor()

    有时,我们希望重新使用同一个Symbol值,Symbol.for方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。如果有,就返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值。
    Symbol.for()和Symbol()都会生成新的Symbol.他们的区别是,Symbol.for()创建的Symbol是全局的,而Symbol()创建的是某个对象的Symbol值。Symbol.for()不会每次调用就返回一个新的Symbol类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。比如,如果你调用Symbol.for("cat")30次,每次都会返回同一个Symbol值,但是调用Symbol("cat")30次,会返回30个不同的Symbol值。

    Symbol.for("bar") === Symbol.for("bar")
    // true
    
    Symbol("bar") === Symbol("bar")
    // false
    

    Symbol.keyFor()返回Symbol.for()创建的Symbol值得key.

    var s1 = Symbol.for('foo');
    Symbol.keyFor(s1);  // 'foo'
    var s2 = Symbol('foo');
    Symbol.keyFor(s2);  // undefined
    
  • 相关阅读:
    sublimetext插件安装
    解决Nextcloud 无法删除目录
    常用文章信息
    使用豆瓣的pip源安装python模块
    top命令的使用
    Centos 7 防火墙 firewalld 简单使用说明
    CentOS 7 时间同步方法
    二进制
    字典
    集合
  • 原文地址:https://www.cnblogs.com/renzhiwei2017/p/7350439.html
Copyright © 2011-2022 走看看