资讯专栏INFORMATION COLUMN

第七元素

王晗 / 1090人阅读

摘要:今天,我们先看看第七种。这就是引入的原因。实际用途当你第一眼看到,你会在想,什么鬼,不想用。注册表每个是唯一的,即使两个描述一样的也不相等。第一句和第二句都是创建一个,不同的是,不再是每次创建不同的,它会从注册表中找,找到了就会返回。

typeof Symbol(): symbol

Javascript 一共有6种数据类型:Undefined、Null、Number、String、Object、Boolean。今天,我们先看看第七种:Symbol。

为什么要产生新的类型

ES5的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是ES6引入Symbol的原因。

可见,这个类型是提供了一个不可更新的特性,这样可以保证别人不会覆盖你的属性。下面我们来看看它的样子:

语法:Symbol([description])

let mySymbol = Symbol();
let mySymbol2 = Symbol("this is just a desction");

没有new,里面的参数只是一个描述,这就是对这个构造器的最简单解释了。

实际用途

当你第一眼看到Symbol,你会在想,什么鬼,不想用。当你知道它的特性,会让你不得不重视它。我们知道,对象的键可以用数字或字符串,但这样的话就不能保证唯一性,当我们知道symbol的特性,就可以拿它来做试验了。

可以作为键名:

let mySymbol = Symbol();
let obj = {};
obj[mySymbol] = "hello";

如此简单的一句,obj对象就使用了mySymbol这个symbol作为键属性,它是一个symbol,不是一个字符串。你不能用点去访问它了,类似的,for-in去枚举一个含有symbol键的对象,也不会打印出来(看例子)。既然它的作用就是保证唯一,我们就可以在这种需求下满足了。

唯一性

let a = "hello";
let b = "hello";

console.log( a === b); // true

let a = Symbol("hello");
let b = Symbol("hello");

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

已有的数据类型,我们很熟悉。再来看看symbol,即使是一样的描述,它们也是不相同的。

举一个例子:

例1

const obj = {
  [Symbol("age")] : 20,
  [Symbol("name")] : "liya",
  ok: true
}

for( var i in obj) {
  console.log(obj[i]);
}

运行之后,你只会得到一个true。for-in 并不能访问到symbol,想要访问,你必须用到专用的api。

例2

log.levels = {
    DEBUG: Symbol("debug"),
    INFO: Symbol("info"),
    WARN: Symbol("warn"),
};
log(log.levels.DEBUG, "debug message");
log(log.levels.INFO, "info message");

咋看也没有什么Symbol的事,事实上在ES5时代,你必须这样写:

log.levels = {
    DEBUG: 1,
    INFO: 2,
    WARN: 3,
};

这样写的坏处是,值不是唯一的,某天如果被人把DEBUG的值改成了3,那你不是顿时懵了。用Symbol的好处在于,你不用理会它的值是什么,它只是一个占位符,并且唯一。

注册表

每个symbol是唯一的,即使两个描述一样的symbol也不相等。symbol的弱封装机制:模块创建了几个symbol,可以在任意对象上使用,无须担心与其它代码创建的属性产生冲突。它只在当前的作用域生效,如果要在全局中共享,就要在全局中注册,使用Symbol.for()去注册。

Symbol("ok");
Symbol.for("ok");

console.log(Symbol("ok") === Symbol("ok"));           // false
console.log(Symbol.for("ok") === Symbol.for("ok"));   // true

第一句和第二句都是创建一个Symbol,不同的是,Symbol.for不再是每次创建不同的symbol,它会从注册表中找,找到了就会返回。无论你访问几次,都不会创建新的symbol。全局的symbol可以跨域和在多个页面中使用。

最后

查了一些资料,但也不是太过清楚,毕竟用的人还不多。期待在ES6后面能够让更多人去使用,类似Symbol这种api,大家只是瞄一眼就不再关注了,除了文档不够,更多的是设计上的问题。ES6出了有一段时间,有多少api能够深入人心,我想只有在坐的各位比较清楚。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80551.html

相关文章

  • 百度前端学院-基础学院-第七天到第八天

    摘要:第五天到第六天的内容没有记笔记,不好不好。第七天到第八天的学习目标是学习布局的各种方式。主要包含相关和相关。定位的元素应该在文档流中的间隙不再存在绝对定位的元素不再存在于正常文档布局流程中。内容较多,请参考学习了容器项第五天到第六天的内容没有记笔记,不好不好。 第七天到第八天的学习目标是:学习布局的各种方式。主要包含position相关和Flexbox相关。 知识点: 1、默认情况下,块级元...

    zombieda 评论0 收藏0
  • [CSS]《CSS揭秘》第七章——结构与布局

    摘要:精确控制表格列宽请注意,为了确保这个技巧奏效,需要为这些表格元素指定一个宽度哪怕是。同样,为了让发挥作用,我们还需要为那一列指定宽度。 自适应内部元素 figure{ max-width: 300px; max-width: min-content;//这个关键字将解析为这个容器内部最大的不可断行元素的宽度( 即最宽的单词、 图片或具有固定宽度的盒元素。 mar...

    Andrman 评论0 收藏0
  • 百度前端学院-基础学院-第七天到第八天之BFC

    摘要:简介全称中文为块级格式化上下文。特征总之记住一句话元素特征表现原则就是内部元素无论怎么翻江倒海,都不会影响外部元素。如何触发,常见如下的值不为的值为,或。的值不为和需掌握自适应模块布局内容很多,具体参考1、BFC简介 BFC全称block formatting context,中文为块级格式化上下文。特征总之记住一句话: BFC元素特征表现原则就是:内部元素无论怎么翻江倒海,都不会影响外部元...

    junfeng777 评论0 收藏0
  • 《java 8 实战》读书笔记 -第七章 并行数据处理与性能

    摘要:正确使用并行流错用并行流而产生错误的首要原因,就是使用的算法改变了某些共享状态。高效使用并行流留意装箱有些操作本身在并行流上的性能就比顺序流差还要考虑流的操作流水线的总计算成本。 一、并行流 1.将顺序流转换为并行流 对顺序流调用parallel方法: public static long parallelSum(long n) { return Stream.iterate(1L...

    刘福 评论0 收藏0
  • 第七课 路径与列表 html5学习2

    摘要:路径一相对路径同级路径下级路径上级路径上一级路径上两级二绝对路径列表列表特点整齐整洁有序一无序列表语法格式注里一般只放标签标签里可以容纳所有元素无序列表会自带样式属性,一般在中修改二有序列表语法格式注里一般只放标签标签里可以容纳所有元素有序1、路径 一、相对路径1、同级路径2、下级路径 /3、上级路径 ../上一级路径 ../../上两级二、绝对路径 2、列表 列表特点;整齐、整洁、...

    stormzhang 评论0 收藏0

发表评论

0条评论

王晗

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<