Symbol 数据类型

  • let s = Symbol();
    
    typeof s;    // "symbol"

是 ES6 继 Number,String,Boolean,Undefined,Null 之后引入的新数据类型

对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型

Symbol 函数的参数只是表示对当前 Symbol 值的描述

  • let s1 = Symbol('foo');
    let s2 = Symbol('bar'); s1 // Symbol(foo)
    s2 // Symbol(bar) s1.toString(); // "Symbol(foo)"
    s2.toString(); // "Symbol(bar)"

凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突

背景:

ES5 的对象属性名都是字符串,这容易造成属性名的冲突

如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。

  • 原始数据类型 Symbol

表示独一无二的值。

它是 JavaScript 语言的第七种数据类型

Symbol 值可以显式转为字符串

Symbol 值可以显式转为布尔值

  • Symbol 值不能与其他类型的值进行运算,会报错
  • 即使 Symbol 函数参数相同,但是它们是不相等的。
  • Symbol 值 作为对象的属性时,只能用 [ ] 访问进行读写

在对象的内部,使用 Symbol 值定义属性时,Symbol 值必须放在方括号之中

  • let s = Symbol();

    let obj = {
    [s]: function (arg) { ... }
    }; obj[s]();
  • 常量使用 Symbol 值最大的好处,就是其他任何值都不可能有相同的值了,因此可以保证上面的switch语句会按设计的方式工作
  • const COLOR_RED    = Symbol();
    const COLOR_GREEN = Symbol(); function getComplement(color) {
    switch (color) {
    case COLOR_RED:
    return COLOR_N:
    return COLOR_GREEN;
    case COLOR_GREERED;
    default:
    throw new Error('Undefined color');
    };
    };
  • 消除魔术字符串的方法,就是把它写成一个变量
  • const shapeType = {
    triangle: Symbol(),
    }; function getArea(shape, options) {
    let area = 0;
    switch (shape) {
    case shapeType.triangle:
    area = .5 * options.width * options.height;
    break;
    };
    return area;
    }; getArea(shapeType.triangle, { width: 100, height: 100 });
  • Symbol 作为属性时,非私有属性,遍历法
  • Symbol 作为属性名,该属性不会出现在for...infor...of循环中,也不会被Object.keys()Object.getOwnPropertyNames()JSON.stringify()返回
  • 但是,它也不是私有属性,有一个 Object.getOwnPropertySymbols() 获取指定对象的所有 Symbol 属性名
  • 重新使用同一个 Symbol 值,Symbol.for('aName')

接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。

  • 如果有,就返回这个 Symbol 值
  • 否则就新建并返回一个以该字符串为名称的 Symbol 值
  • let s1 = Symbol.for('foo');    // 登记在全局环境中供搜索
    let s2 = Symbol.for('foo'); // 登记在全局环境中供搜索 s1 === s2 // true

Symbol.for()Symbol()这两种写法,都会生成新的 Symbol。

它们的区别是:

前者会被登记在全局环境中供搜索,后者不会。

Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。

比如,如果你调用Symbol.for("cat")30 次,每次都会返回同一个 Symbol 值,

但是调用Symbol("cat")30 次,会返回 30 个不同的 Symbol 值

  • Symbol.keyFor() 返回一个已登记的 Symbol 类型值的 key,即 Symbol.for() 生成的 Symbol 值
  • 注意: 为 Symbol 值登记的名字,是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值
  • let obj = {
    [Symbol('my_key')]: 1,
    enum: 2,
    nonEnum: 3
    }; Reflect.ownKeys(obj); // ["enum", "nonEnum", Symbol(my_key)]

ECMA Script 6_Symbol() 唯一类型值声明函数_Symbol 数据类型的更多相关文章

  1. c++学习笔记之基础---类内声明函数后在类外定义的一种方法

    在C++的“类”中经常遇到这样的函数, 返回值类型名 类名::函数成员名(参数表){ 函数体.} 双冒号的作用 ::域名解析符!返回值类型名 类名::函数成员名(参数表) { 函数体. } 这个是在类 ...

  2. ECMA Script 6_唯一容器 Set_映射容器 Map

    唯一容器 Set ES6 提供了新的数据结构 Set Set 结构没有键名,只有键值(或者说 键名 和 键值 是同一个值) 它类似于数组,但是成员的值都是唯一的,没有重复的值 Set 内部判断两个值是 ...

  3. ECMA Script 6_symbol(symbol.iterator) 新接口_iterator接口

    iterator 接口 只要部署了 iterator 接口 symbol(symbol.iterator), 则可以进行 for...of  遍历

  4. C++中怎么获取类的成员函数的函数指针?

    用一个实际代码来说明. class A { public: staticvoid staticmember(){cout<<"static"<<endl;} ...

  5. 你好,C++(32) 类是对现实世界的抽象和描述 6.2.1 类的声明和定义

    6.2  类:当C++爱上面向对象 类这个概念是面向对象思想在C++中的具体体现:它既是封装的结果,同时也是继承和多态的载体.因此,要想学习C++中的面向对象程序设计,也就必须从“类”开始. 6.2. ...

  6. C++多态性中基类析构函数声明为虚函数

    在用基类指针指向派生类时, 在基类析构函数声明为virtual的时候,delete基类指针,会先调用派生类的析构函数,再调用基类的析构函数. 在基类析构函数没有声明为virtual的时候,delete ...

  7. TypeScript基础类型,类实例和函数类型声明

    TypeScript(TS)是微软研发的编程语言,是JavaScript的超集,也就是在JavaScript的基础上添加了一些特性.其中之一就是类型声明. 一.基础类型 TS的基础类型有 Boolea ...

  8. (C++)浅谈多态基类析构函数声明为虚函数

    主要内容: 1.C++类继承中的构造函数和析构函数 2.C++多态性中的静态绑定和动态绑定 3.C++多态性中析构函数声明为虚函数 1.C++类继承中的构造函数和析构函数 在C++的类继承中, 建立对 ...

  9. c++学习笔记之基础---类内声明线程函数的调用

    近日需要将线程池封装成C++类,类名为Threadpool.在类的成员函数exec_task中调用pthread_create去启动线程执行例程thread_rounter.编译之后报错如下: spf ...

随机推荐

  1. Java基础知识拾遗(一)

    类型提升规则 Java定义了几个应用于表达式的类型提升规则:所有byte.short和char类型的值都被提升为int类型.如果有一个操作数是long类型,将这个表达式提升为 long 类型:如果有一 ...

  2. EF CodeFirst系列(2)---CodeFirst的数据库初始化

    1. CodeFirst的默认约定 1.领域类和数据库架构的映射约定 在介绍数据库的初始化之前我们需要先了解领域类和数据库之间映射的一些约定.在CodeFirst模式中,约定指的是根据领域类(如Stu ...

  3. React 记录(6)

    React文档:https://www.reactjscn.com/docs/react-component.html 慢慢学习:对照教程文档,逐句猜解,截图 React官网:https://reac ...

  4. HTML(一)HTML基础语法(HTML简介,HTML文档声明)

    HTML 概念介绍 [概念] (Hyper Text Markup Language)超文本标记语言,是用来描述网页的一种语言 超文本(Hyper Text):不只包括文本,也可以包括图片.链接.音乐 ...

  5. [物理学与PDEs]第5章习题3 第二 Piola 应力张量的对称性

    试证明: 在物质描述下, 动量矩守恒定律等价于第二 Piola 应力张量的对称性. 证明: 由 $$\beex \bea \int_{G_t}\rho\sex{{\bf y}\times\cfrac{ ...

  6. 散度、旋度与 Laplacian

    $$\bex -\lap {\bf u}=\rot \rot {\bf u}-\n \Div {\bf u}. \eex$$

  7. Educational Codeforces Round 32 E. Maximum Subsequence

    题目链接 题意:给你两个数n,m,和一个大小为n的数组. 让你在数组找一些数使得这些数的和模m最大. 解法:考虑 dfs但是,数据范围不允许纯暴力,那考虑一下折半搜索,一个从头开始往中间搜,一个从后往 ...

  8. notepad++ 代码注释快捷键

    在用notepad++进行代码编辑的过程中 单行.多行注释            //方式          :ctrl+k 取消单行.多行.区块注释                 :ctrl+sh ...

  9. Android Studio项目Gradle内网配置

    由于内网无法连接到外部网络,在使用Gradle编译Android Studio项目时就会面临一些问题: 1.Gradle安装文件无法下载 2.Gradle Android插件无法下载 3.项目依赖文件 ...

  10. 2017-2018-2 165X 『Java程序设计』课程 结对编程练习_四则运算

    2017-2018-2 165X 『Java程序设计』课程 结对编程练习_四则运算 经过第一阶段的学习,同学们已经熟悉了这门语言基本的用法.在一次又一次对着电脑编写并提交代码,进行练习的时候,有没有觉 ...