美文网首页
ES6 新数据类型 symbol

ES6 新数据类型 symbol

作者: hengking | 来源:发表于2019-05-06 10:14 被阅读0次
    • 预热

    javascript有 6种 数据类型

    1. undefined
    2. null
    3. 布尔值(Boolean)
    4. 字符串(String)
    5. 数值(Number)
    6. 对象(Object)

    而 symbol 为ES6新增的数据类型。表示独一无二的值,使用Symbol()定义(S大写!)

    • 理解symbol

    那么这个symbol到底是个什么东西,我们看下面例子:

    const a = Symbol()
    const b = Symbol()
    console.log(a==b) // false
    

    在我理解,就是对a、b进行随机赋值,并且永远不会重复

    再来一个例子

    const b = Symbol();
    let a = {};
    a[b] = 'red';
    console.log(a[b]); // red
    console.log(a) // {Symbol(): "red"}
    a = {
        [b]: 'blue',
        b: 'black'
    }
    console.log(a); // {b: "black", Symbol(): "blue"}
    a.b = 'yellow'
    console.log(a); //{b: "yellow", Symbol(): "blue"}
    a[b] = 'black'
    console.log(a); //{b: "yellow", Symbol(): "black"}
    a['b'] = 'white'
    console.log(a); // {b: "white", Symbol(): "black"}
    

    我们可以看到,如果用Symbol()生成的symbol在对象中显示的是Symbol()而不对定义的b,
    而需要对symbol值进行修改则需要使用a[b];通过这里我们可以看到symbol的一个使用好处就是不会被不经意的a.b修改了值

    • symbol使用
    1. 写法
    let mySymbol = Symbol();
    
    // 第一种写法
    let a = {};
    a[mySymbol] = 'Hello!';
    
    // 第二种写法
    let a = {
      [mySymbol]: 'Hello!'
    };
    
    // 第三种写法
    let a = {};
    Object.defineProperty(a, mySymbol, { value: 'Hello!' });
    
    // 以上写法都得到同样结果
    a[mySymbol] // "Hello!"
    
    1. 添加描述
    const sym = Symbol('name');
    console.log(sym); // Symbol(name)
    

    定义在Symbol()内添加描述
    ES2019 提供方法descripttion

    const sym = Symbol('name');
    console.log(sym.description); // name
    
    1. 赋值
    let mySymbol = Symbol();
    
    // 第一种写法
    let a = {};
    a[mySymbol] = 'Hello!';
    
    // 第二种写法
    let a = {
      [mySymbol]: 'Hello!'
    };
    
    // 第三种写法
    let a = {};
    Object.defineProperty(a, mySymbol, { value: 'Hello!' });
    
    // 以上写法都得到同样结果
    a[mySymbol] // "Hello!"
    
    1. 遍历

    Symbol 作为属性名,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。但是,它也不是私有属性,有一个Object.getOwnPropertySymbols方法,可以获取指定对象的所有 Symbol 属性名
    《ECMAscript 6入门》 ——阮一峰

    如果要遍历symbol则需要使用 Object.getOwnPropertySymbols 方法

    const a = Symbol('a')
    const b = Symbol('b')
    const symList = {
        [a]: 1,
        [b]: 2
    }
    console.log(Object.getOwnPropertySymbols(symList)); // [Symbol(a), Symbol(b)]
    

    Object.getOwnPropertyNames方法得不到Symbol属性名;

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

    1. Symbol.for(),Symbol.keyFor()
      一开始我们说过symbol的概念,symbol为唯一的;但是我们非要使用相同的symbol值呢;
      这时候我们就得用 Symbol.for()
    const a = Symbol.for('c')
    const b = Symbol.for('c')
    console.log(a == b); // true
    console.log(a); // Symbol(c)
    

    获取Symbol.for()定义的描述可以通过 Symbol.keyFor() 来获取,但是如果是通过Symbol()写的描述就获取不到了

    const a = Symbol.for("c");
    console.log(Symbol.keyFor(a)); // c
    const b = Symbol("c");
    console.log(Symbol.keyFor(b)); // undefined
    
    1. 代码中使用/使用场景
      比如我们要进行判断,而判值提前定义为常量
    const a = 'NAME_A'
    const b = 'NAME_B'
    const c = 'NAME_C'
    function Func(val) {
        switch (val) {
            case a:
                return 1
            case b:
                return 2
            case c:
                return 3
            default:
                return -1
        }
    }
    console.log(Func(a)); // 1
    

    这里我们并不关心obj里对象值是什么此时我们使用Symbol()

    const a = Symbol('a')
    const b = Symbol('b')
    const c = Symbol('c')
    function Func(val) {
        switch (val) {
            case a:
                return 1
            case b:
                return 2
            case c:
                return 3
            default:
                return -1
        }
    }
    console.log(Func(a)); // 1
    

    that all

    相关文章

      网友评论

          本文标题:ES6 新数据类型 symbol

          本文链接:https://www.haomeiwen.com/subject/tzoloqtx.html