最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 《看完就懂系列》答应我,看完就开始用Symbol好吗?

    正文概述 掘金(南极大冰块)   2021-01-16   455

    写在前面

    每到周五公司就格外的忙,测试忙着提bug,产品忙着改需求,UI忙着发挥她的像素眼,尤其是下班前的一阵子,大家彷佛充满了干劲,颇有种再干他五百年的气势。就像一天的活都堆到傍晚,一周的活也都堆到周五,一言不合就加班。更惨的是加班回家还要哄女朋友睡觉,大冰块日更的大业差点被毁于一旦。

    终于把女朋友哄睡着了,大冰块悄悄爬起床找个简单又冷门的题材再更它一篇。

    很久很久之前,大冰块面试的时候,面试官问我js的数据类型,我想这还不简单?脱口而出Number 、 String 、 Boolean 、 Object、 null 和 undefined ,还把它们的基本方法也说了一遍。面试官却意犹未尽的说:还有呢?ES6新增的Symbol有用到吗?我说项目中暂时没有用到过,贵公司有用到吗?面试官迟疑了一会儿说没有。

    我和面试官面面相觑,气氛一度有些尴尬。

    所以今天就来说说这个Symbol,避免下次面试的时候尴尬。

    什么是Symbol

    Symbol 是ES6新增的一种基本数据类型。我们可以通过调用内置函数 Symbol() 创建,这个函数会动态的生成一个匿名、全局唯一的值。

    举个例子吧:

    Symbol就好比我们的身份证号,没有谁的身份证号和别人是相同的,都是全国唯一的号码。

    如:

    let a = Symbol()
    let b = Symbol()
    a === b // false
    

    因为上述例子中,a和b的值都是Symbol(),虽然它们并不相等,但是我该如何区分它们呢?这里有个对Symbol不错的说明:

    这时候就可以给Symbol()函数传参,参数可作为当前Symbol值的描述,即Symbol(描述内容)

    读取描述内容可通过Symbol值转字符串的方法,也可通过Symbol值的属性description直接获取描述内容。示例如下:

    const a = Symbol('描述啊');
    
    String(a) // "Symbol(描述啊)"
    a.toString() // "Symbol(描述啊)"
    a.description  // "描述啊"
    
    // 注意:Symbol()返回的永远是全局唯一的值。
    // 所以Symbol() 和 Symbol() 并不相等。同样的,Symbol("描述")和Symbol("描述")也不相等哦。
    

    Symbol有什么用

    作为一名务实主义者,不知道它的用处就想让我去了解它,那是不可能的。

    什么?你说不先了解怎么知道它的用处?这不就是“不工作怎么有经验?没经验怎么找工作?”的神奇悖论吗?

    啊不扯了,我来告诉你Symbol最基本的两个用处

    第一个用处容易理解,比如:

    // 有一天大冰块声明了一个对象
    let obj = {
        a:1,
        b:2,
        ...
    }
    
    // 过了很久,同事小明用到了这个对象,不过因为对象里键值对繁多,并没有仔细筛查,小明给对象添加了新的键值对
    obj.a = 100 
        
    // 此时obj的值为
    obj = {
        a:100,
        ...
    }
    
    // 如果其他地方在用obj.a的值,就会出现一系列的错误
    
    // 所以小明给obj对象添加属性时,可以写成
    
    const a = Symbol('a');
    obj[a] = 100;
    
    // 此时obj的值为
    obj = {
        a: 1,
        b: 2,
        Symbol(a): 100
    }
    
    

    而第二个用处就不太好理解了,我们要先理解魔术字符串的含义。

    以我最近在项目中看到的某位小伙伴代码为例:

    const getUserInfo = state => {
    	if(state == 'yes'){
        	 // 状态正确的后续操作
        }else if(state == 'no'){
         	 // 状态错误的后续操作        
         }else{
             // 其他状态的后续操作
    	}
    }
    
    // 在上述代码中,getUserInfo函数的传参"yes"和"no"都是魔术字符串,它们在多个接口中都被用到,不利于将来的修改和维护。
    // Symbol适用于原先写成魔术字符串的地方,因为它能保证自己是全局唯一的值。
    
    // 所以代码可改写如下
    let status = {
        success: Symbol('success'),
        error: Symbol('error'),
        ...
    }
    const getUserInfo = state => {
    	if(state === status.success){
        	 // 状态正确的后续操作
        }else if(state === status.error){
         	 // 状态错误的后续操作        
         }else{
             // 其他状态的后续操作
    	}
    }
    
    getUserInfo(status.success)
    

    值得一提的是:

    Symbol 作为对象属性名时读取时不能用.运算符,要用方括号。

    以下面代码为例:

    let state = Symbol()
    let obj = {}
    obj[state] = 500
    obj.state = 600
    obj // {state: 600, Symbol(): 500}
    

    这是因为.运算符后面是字符串,所以取到的是字符串 state属性,而不是 Symbol 值 state属性。

    另外需要注意的是:

    以下面代码为例:

    const obj = {};
    const a = Symbol('a');
    obj[a] = 'a';
    for (let i in obj) {
      console.log(i); // 无输出
    }
    Object.getOwnPropertyNames(obj) // []
    Object.getOwnPropertySymbols(obj) // [Symbol(a)]
    

    Symbol的方法

    Symbol.for()

    既然Symbol()生成的是一个全局唯一的值,那我们如果想重复使用某个Symbol()生成的值怎么办呢?

    这时候就需要用到Symbol.for()方法了。

    以下面代码为例:

    let a = Symbol.for("唯一的")
    let b = Symbol.for("唯一的")
    a === b // true
    

    在上面的代码中,let a时全局检索有没有以"唯一的"作为描述值的 Symbol 值,发现没有就创建了一个Symbol.for("唯一的")let b时全局检索有没有以"唯一的"作为描述值的 Symbol 值,发现有,于是直接把找到的Symbol.for("唯一的")赋值给了b,并没有重新去生成一个全局唯一的值。所以a === btrue

    Symbol.keyFor()

    如果我们要获取到全局注册的 Symbol 类型值的描述值该怎么做呢?

    这时候就可以使用Symbol.keyFor()方法了。

    以下面代码为例:

    let a = Symbol.for("唯一的")
    let b = Symbol("唯一的")
    Symbol.keyFor(a) // 唯一的
    Symbol.keyFor(b) // undefined
    

    在上面的代码中,let aSymbol.for()方法生成了一个全局注册的描述值为"唯一的"的Symbol值,所以Symbol.keyFor(a)返回了描述值"唯一的"

    let bSymbol()方法生成的值并不是全局注册的。所以Symbol.keyFor(b)直接返回了undefined

    写在后面

    看完了看懂了不代表自己真的掌握了,如果想要熟练的掌握并应用,还是离不开平时的使用和积累。所以希望看到这里的你下次就能在项目中用到Symbol,有时候一段简单的代码,就能让老同事对你刮目相看,让新同事觉得你深不可测哟~

    这是大冰块《看完就懂系列》的第7篇文章,《看完就懂系列》旨在把一些常见的概念或方法以通俗易懂的方式呈现出来。欢迎大家点击其他文章一起讨论学习:

    • 《看完就懂系列》谈谈数据埋点的原理与实现
    • 《看完就懂系列》Ajax是不是凭一己之力造就了整个前端的生态圈?
    • 《看完就懂系列》项目中的权限管理复杂吗?
    • 《看完就懂系列》天哪!搞懂节流与防抖竟简单如斯~
    • 《看完就懂系列》15个方法教你玩转字符串
    • 《看完就懂系列》字符串截取方法substr() 、 slice() 和 substring()之间的区别和用法

    《看完就懂系列》答应我,看完就开始用Symbol好吗?


    起源地下载网 » 《看完就懂系列》答应我,看完就开始用Symbol好吗?

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元