美文网首页
ES6 - Symbol

ES6 - Symbol

作者: ElricTang | 来源:发表于2019-10-15 17:57 被阅读0次

    ES6新增了基本数据类型Symbol,最大的特点是每个Symbol都是唯一的。(解决变量冲突问题)

    let a = Symbol();
    let b = Symbol();
    console.log(a === b); // false
    

    一. 使用typeof测试类型时,返回symbol,因为symbol是基本数据类型

    console.log(typeof(Symbol()));// symbol
    

    二. 无法对Symbol()使用new,因为Symbol产生的是原始值,而不是包装对象,也意味着无法像对象一样添加属性。

    let c = new Symbol();// TypeError: Symbol is not a constructor
    

    三. Symbol()接受参数,用于作为描述(方便区分不同symbol实例)

    let tom = Symbol('tom');
    let jack = Symbol('jack');
    console.log(tom);// Symbol(tom)
    console.log(jack);// Symbol(jack)
    

    注意:参数只是描述符,与symbol的值没有关系,相同的参数不会使值相等

    console.log(Symbol('a') === Symbol('a'));// false
    

    四. 关于symbol类型转换

    • symbol无法被隐式转换为string
    console.log('my name is' + Symbol('tom'));
    // TypeError: Cannot convert a Symbol value to a string
    
    • 但是,symbol可以显式转换为string
    console.log(Symbol('tom').toString());// Symbol(tom)
    
    • symbol可以转换为boolean(显式转换、隐式转换都可以)
    console.log(Boolean(Symbol()));// true
    console.log(!Symbol());// false
    
    • symbol无法转换为number(显式转换、隐式转换都不可以)
    console.log(Symbol(1) + 1);
    // TypeError: Cannot convert a Symbol value to a number
    console.log(Number(Symbol(1)));
    // TypeError: Cannot convert a Symbol value to a number
    

    五. symbol的枚举

    • 使用for in无法获取对象中的symbol属性
    const name = Symbol('name');
    const age = Symbol('age');
    
    let obj = {
        [name]:'tom',
        [age]:21,
        'hobby':'football'
    };
    
    for(let item in obj){
        console.log(item,obj[item]);
    }
    // hobby football
    
    • Object.getOwnPropertyNames()也无法获取遍历到symbol属性
    console.log(Object.getOwnPropertyNames(obj));// [ 'hobby' ]
    - 
    
    • in操作符无法判断symbol
    console.log([name] in obj);
    // TypeError: Cannot convert a Symbol value to a string
    
    • hasOwnProperty()无法判断symbol
    console.log(obj.hasOwnProperty([name]));
    // TypeError: Cannot convert a Symbol value to a string
    
    • JSON.stringify()转换时也会忽略symbol
    console.log(JSON.stringify( { name:'tom',[Symbol('age')]:21 } ))
    // {"name":"tom"}
    
    • 正确遍历symbol的方法:
      1. Object.getOwnPropertySymbols()
      const name = Symbol('name');
      const age = Symbol('age');
      let obj = {
         [name]:'tom',
         [age]:21,
         hobby:'football'
      };
      console.log(Object.getOwnPropertySymbols(obj));
      // [ Symbol(name), Symbol(age) ]
      
      1. Reflect.ownKeys()
      const name = Symbol('name');
      const age = Symbol('age');
      let obj = {
         [name]:'tom',
         [age]:21,
         hobby:'football'
      };
      console.log(Reflect.ownKeys(obj));
      // [ 'hobby', Symbol(name), Symbol(age) ]
      

    六. symbol的应用

    • 作为对象的属性名,因为唯一性,symbol作为属性名能避免命名冲突(覆盖)
    const name = Symbol('name');
    
    let obj1 = {};
    obj1[name] = 'tom';
    
    let obj2 = {
        [name]:'tom'
    };
    
    let obj3 = {};
    Object.defineProperty(obj3,name,{
        value:'tom'
    });
    

    调用对象中以symbol为属性名的属性时,只能使用[]的方式,不能使用.,定义属性时同理。(因为点运算符默认接字符串)

    console.log(obj1.name);// undefined
    console.log(obj1[name]);// tom
    console.log(obj1['name']);// undefined
    

    相关文章

      网友评论

          本文标题:ES6 - Symbol

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