ES6---Symbol

一、第七种数据类型–Symbol

  • ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型。
  • 因为对象的属性名可能会冲突,所以引入了Symbol数据类型。
  • Symbol 值通过Symbol函数生成。对象的属性名现在可以有两种类型
  1. 一种是原来就有的字符串
  2. 另一种就是新增的 Symbol 类型
  • 凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
  • Symbol 函数栈不能用 new 命令,因为 Symbol 是原始数据类型,不是对象。可以接受一个字符串作为参数,为新创建的 Symbol 提供描述,用来显示在控制台或者作为字符串的时候使用,便于区分。
           let s1 = Symbol();
           let s2 = Symbol();
           console.log(typeof s1);//symbol
    let sym=Symbol("abc");
    let sym1=Symbol("abc");
    console.log(sym, sym1);//Symbol(abc) Symbol(abc)
    console.log(sym === sym1);//false 

二、Symbol类型的转化

       let str = "abc";
       let s3 = Symbol(str);
       console.log(s3);//Symbol(abc)--字符串
  • 如果Symbol的参数是一个对象,就会调用该对象的toString方法,将其转为字符串,然后生成一个Symbol值。
       let obj = {
           //重写toString方法
           name:"赵佳敏",
           toString(){
               return this.name;
           }
       }
       //obj直接转字符串
       console.log(obj.toString());//赵佳敏
       let s4 = Symbol(obj);
       console.log(s4);//Symbol(赵佳敏)
  • 注:Symbol函数的参数只是表示对当前Symbol值的描述,因此相同参数的Symbol函数的返回值是不相等的。
  • 无参数:
       let s1 = Symbol();
       let s2 = Symbol();
       console.log(s1 === s2);//false
  • 有参数
       let s1 = Symbol('abc');
       let s2 = Symbol('abc');
       console.log(s1 === s2);//false
  • 那么,为什么会出现上述情况呢?
  • 是因为Symbol变量是独一无二的。

三、Symbol.prototype.description–直接获取字符串值

  • 创建Symbol的时候,可以添加一个描述,但是读取这个描述需要将Symbol显式转为字符串。

Symbol变量直接转为字符串

  • 方法1:
       let s1 = Symbol('abc');
       console.log(s1.toString());//Symbol(abc)
  • 方法2:通过String类直接转化
		console.log(String(s1));//Symbol(abc)
  • 方法3:
  • es2019中更新了一个属性,描述唯一变量,直接返回 Symbol 的描述。
        console.log(s1.description);//abc

四、作为属性名的Symbol

  • Symbol 作为对象属性名时不能用.运算符,要用方括号。因为.运算符后面是字符串,所以取到的是字符串 sys 属性,而不是 Symbol 值 sys 属性。

1. 直接作为属性名

    let sys=Symbol("name");
    let obj={};
    obj[sys]="zjm";
    console.log(obj);//{Symbol(name): "zjm"}
    //不能直接对象点属性获取值
    console.log(obj.sys);//undefined
    console.log(obj[sys]);//zjm 

2. 对象属性字面量–对象的属性是变量

    //对象属性字面量(对象的属性是变量)
    //对象属性式变量,解析直接[]
    let sys=Symbol("list");
    let obj={
        [sys]:'abc'
    }
    console.log(obj);//{Symbol(list): "abc"}
    console.log(obj.sys);//undefined
    console.log(obj[sys]);//abc 

3. 通过原生js操作对象属性赋值

    //通过原生js操作对象属性赋值
    let sys=Symbol('list');
    let obj={};
    Object.defineProperty(obj,sys,{
        value:'zjm'
    })
    console.log(obj);//{Symbol(list): "zjm"}
    console.log(obj.sys);//undefined
    console.log(obj[sys]);//zjm 

五、消除魔术字符串

  • 魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。风格良好的代码,应该尽量消除魔术字符串,改由含义清晰的变量代替。
  • 常用的消除魔术字符串的方法,就是把它写成一个变量。
  • 尽量实现代码全动态,不要太固定,不然不利于后期修改。
    let fun = (shop,obj) => {
        let count = 1;
        let price = 0;
        switch(shop){
            case 'weixin':
                count=0.9;
                price = count*obj.price*obj.num;
                break;
            case 'zhifubao':
                count=0.85;
                price = count*obj.price*obj.num;
                break;
            case 'xianjin':
                count=0.95;
                price = count*obj.price*obj.num;
                break;
        }
        return price;
    }
    var allprice = fun('xianjin',{price:120,num:5});
    console.log(allprice);//570
  • 消除魔术字符串
       let way = [
           {
               type:'weixin',
               count:0.9
           },
           {
               type:'zhifubao',
               count:0.85
           },
           {
               type:'xianjin',
               count:0.95
           }
       ]
       let fun = (shop,obj) => {
           let f1 = 1;
           let price = 0;
           switch(shop.type){
               case shop.type:
                   f1 = shop.count;
                   price = f1*obj.price*obj.num;
                   break;
           }
           return price;
       }
       var allprice = fun(way[2],{price:120,num:5});
       console.log(allprice);//570

六、Symbol.for(),Symbol.keyFor()

1.Symbol.for()

  • Symbol.for() 类似单例模式,首先会在全局搜索被登记的 Symbol 中是否有该字符串参数作为名称的 Symbol 值,如果有即返回该 Symbol 值,若没有则新建并返回一个以该字符串参数为名称的 Symbol 值,并登记在全局环境中供搜索。
  • 如果想重新使用同一个 Symbol 值,Symbol.for()方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局。
  • 创建两个Symbol()变量,两个变量是不恒等的。
       let k1 = Symbol('ab');
       let k2 = Symbol('ab');
       console.log(k1 === k2);//false
  • 想要使用同一个Symbol值,即k1 === k2返回true。
  • 使用Symbol.for()方法,返回同一个Symbol值
       let s3 = Symbol.for('abc');
       let s4 = Symbol.for('abc');
       console.log(s3 === s4);//true
  • Symbol.for()与Symbol()这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。比如,如果你调用Symbol.for(“cat”)30 次,每次都会返回同一个 Symbol 值,但是调用Symbol(“cat”)30 次,会返回 30 个不同的 Symbol 值。

2.Symbol.keyFor()

  • Symbol.keyFor()方法返回一个已登记的 Symbol 类型值的key。
  • Symbol.keyFor() 返回一个已登记的 Symbol 类型值的 key ,用来检测该字符串参数作为名称的 Symbol 值是否已被登记。
       let k5 = Symbol('abc');
       let k6 = Symbol.for('abc');
       console.log(k5 === k6);//false
       //直接生成一个对应的Symbol变量
       console.log(Symbol.keyFor(k5));//undefined
       //返回的就是原始字符串
       console.log(Symbol.keyFor(k6));//abc
  • 使用Symbol.for()方法会去Symbol的注册表中注册一个key值,再去声明的时候会去找对应的key值,如果没有,重新生成一个Symbol变量。
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南初️

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值