Symbol

2017-08-28  本文已影响15人  keknei

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的几个特性的介绍这么多,想看更详细的资料,请狠狠的点击我


上一篇下一篇

猜你喜欢

热点阅读