Symbol

作者: keknei | 来源:发表于2017-08-28 23:04 被阅读15次

    js中除了undefined number function string object null Boolean,es6新加了一种类型Symbol

    {
        let s1=Symbol();
        let s2=Symbol();
        console.log(s1);//Symbol()
        console.log(s2);//Symbol()
        console.log(typeof s1);//Symbol
        console.log(s1==s2);//false
    }
    
    很明显,symbol都是不相等,这是最关键的特性

    然后继续往下看,要是symbol传个参数呢

    {
    //传字符串
      let s1=Symbol('string');
      let s2=Symbol('string');
      console.log(s1);//Symbol(string)
      console.log(s2);//Symbol(string)
      console.log(s1==s2);//false
    
      //传数组
      const s3=Symbol([1,2,3]);
      const s4=Symbol([1,2,3]);
      console.log(s3);//Symbol(1,2,3)
      console.log(s4);//Symbol(1,2,3)
      console.log(s3==s4);//false
     //传对象
      const json={a:1};
      const s5=Symbol(json);
      const s6=Symbol(json);
      console.log(s5);//Symbol([object Object])
      console.log(s6);//Symbol([object Object])
      console.log(s5==s6);//false
    }
    
    以上例子可以看出,Symbol函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的Symbol函数的返回值是不相等的。

    如果想把symbol转化成其他类型,改摆什么姿势才行呢,继续往下看

    {
        //Symbol 值可以显式转为字符串。
         const s=Symbol('string');
         //console.log('hello'+s);//Cannot convert a Symbol value to a string
         console.log('hello'+String(s));//helloSymbol(string)
         console.log('hello'+s.toString(s));//helloSymbol(string)
    
         //Symbol 值也可以转为布尔值,但是不能转为数值。
         console.log(Boolean(s));//true
         const b=Symbol(1);
         //Number(b);// Cannot convert a Symbol value to a number
    }
    

    json对象中使用symbol作为属性,几个注意点

    {
        let s=Symbol();
        let obj={
             [s]:'symbol',
             s:'hello'
        }
        console.log(obj[s]);//symbol
        console.log(obj.s);//hello
        //Symbol 值作为对象属性名时,不能用点运算符。用中括号
    }
    

    属性名的遍历

    {
         let s=Symbol();
         let b=Symbol();
         let obj={
              [s]:'symbol',
              s:'hello',
              [b]:'world'
          }
          for (let name in obj){
            console.log(name);//s
          }
         for (let val of Object.values(obj)){
            console.log(val);//hello
         }
         //Symbol 作为属性名,该属性不会出现在for...in、for...of循环中
    
    
         //下面这个方法循环出属性名是symbol类型的属性值
         let arr=Object.getOwnPropertySymbols(obj);
         console.log(arr);//[Symbol(), Symbol()]
         for (let i of Object.values(arr)){
            console.log(obj[i]);//symbol world
         }
    
         //如果都想循环出来的话,Reflect.ownKeys方法可以返回所有类型的键名
         let arrs=Reflect.ownKeys(obj);
         for (let name of Object.values(arrs)){
           console.log(obj[name]);//hello symbol world
        }
    }
    

    看一下Symbol.for(),Symbol()的区别

    {
        console.log(Symbol()===Symbol());//false
        console.log(Symbol.for()===Symbol.for());//true
    }
    

    Symbol.for()与Symbol()这两种写法,都会生成新的Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。比如,如果你调用Symbol.for("cat")30次,每次都会返回同一个 Symbol 值,但是调用Symbol("cat")30次,会返回30个不同的Symbol值

    Symbol.keyFor的用法

    {
        let s1=Symbol('s1');
        let s2=Symbol.for('s2');
        console.log(Symbol.keyFor(s1));//undefined
        console.log(Symbol.keyFor(s2));//s2
    }
    
    Symbol.keyFor方法返回一个已登记的 Symbol 类型值的key,这个方法针对Symbol.for()是ok的,但是对Symbol()是挂掉的,返回的是个undefined



    ok,按照国际惯例,咱们得来这么一下子
    Symbol的几个特性的介绍这么多,想看更详细的资料,请狠狠的点击我


    相关文章

      网友评论

          本文标题:Symbol

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