ES6 Symbol

2023-11-12

概览

const mySymbol = Symbol('mySymbol');
console.log(mySymbol); // Symbol(mySymbol)
console.log(mySymbol === Symbol('mySymbol')); // false
console.log(typeof mySymbol); // 'symbol'

基本数据类型Symbol

ES6 六种基本数据类型: StringNumberBooleanNullUndefinedSymbol
ES6 七种数据类型:StringNumberBooleanNullUndefinedObjectSymbol

类型转换

  • 转字符串(不支持强制转换成字符串)
// 转String
console.log(mySymbol.toString()); // 'Symbol(mySymbol)'
console.log(String(mySymbol)); // 'Symbol(mySymbol)'
// console.log(mySymbol + ''); // Cannot convert a Symbol value to a string
// console.log(`${mySymbol}`); // Cannot convert a Symbol value to a string
  • 转Boolean
// 转Boolean  
console.log(Boolean(mySymbol)); // true
console.log(!mySymbol); // false
if(mySymbol){
  console.log(123); // 123
}
  • 转Number(不支持)
// console.log(Number(mySymbol)); //Uncaught TypeError: Cannot convert a Symbol value to a number
// console.log(+mySymbol); //Uncaught TypeError: Cannot convert a Symbol value to a number
// console.log(1+mySymbol); //Uncaught TypeError: Cannot convert a Symbol value to a number

自定义Symbol属性键

  • 第一种方法
let ourSymbol = Symbol();
let a = {};
a[ourSymbol] = 'hello'; 
console.log(a); // {Symbol(): "hello"}
  • 第二种方法
let ourSymbol = Symbol();
let b = {
  [ourSymbol]: 'world'
};
console.log(b); // {Symbol(): "world"}
  • 第三种方法
let ourSymbol = Symbol();
let c = {};
Object.defineProperty(c,ourSymbol,{value: '!'});
console.log(c); // {Symbol(): "!"}

注意:不支持点运算符

let ourSymbol = Symbol();
a.ourSymbol = '点运算符';
console.log(a[ourSymbol]); // undefined
console.log(a['ourSymbol']); // '点运算符'

注意:在对象内部,使用Symbol值定义属性时,Symbol值必须放在方括号中。

let s = Symbol();
let objNew = {
  [s]:function(arg){
    console.log(arg);
  }
};
let objNew1 = {
  [s](arg){
    console.log(arg);
  }
};
objNew[s](123)
objNew1[s](234)

Symbol作为属性键

const MY_KEY = Symbol();
const MY = Symbol();
const FOO = Symbol();
const objkEY = {
  [MY]:333,
  [FOO](fo){
    return fo
  }
};
objkEY[MY_KEY] = 123;
console.log(objkEY[MY_KEY]); // 123
console.log(objkEY[MY]); // 333
console.log(objkEY[FOO](11)); // 11

枚举属性键

const keyObj = {
  [Symbol('my_key')]: 1,
  enum: 2,
  nonEnum: 3
}
Object.defineProperty(keyObj, 'nonEnum', {enumerable: false});
console.log(keyObj); // {enum: 2, nonEnum: 3, Symbol(my_key): 1}
console.log(Object.getOwnPropertyNames(keyObj)); // 忽略Symbol属性键:["enum", "nonEnum"]
console.log(Object.getOwnPropertySymbols(keyObj)); // 忽略字符串属性键:[Symbol(my_key)]
console.log(Reflect.ownKeys(keyObj)); // 遍历所有属性键:["enum", "nonEnum", Symbol(my_key)]
console.log(Object.keys(keyObj)); // 遍历可枚举字符串属性键:["enum"]

Symbol用来表示概念

用于定义一种常量,保证这组常量不相等

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

其他任何值都不能有相同的值————保证switch语句设计的方式工作

const COLOR_RED = Symbol();
const COLOR_GREEN = Symbol();
function getComplement(color) {
  switch(color) {
    case COLOR_RED:
      return COLOR_GREEN;
    case COLOR_GREEN:
      return COLOR_RED;
    default: 
      throw new Error('undefined')
  }
}
console.log(getComplement(COLOR_RED));
console.log(getComplement(COLOR_GREEN));
// console.log(getComplement('21321'));

Symbol的方法和属性

console.dir(Symbol);
// ƒ Symbol()
// arguments: (...)
// asyncIterator: Symbol(Symbol.asyncIterator)
// caller: (...)
// for: ƒ for()
// hasInstance: Symbol(Symbol.hasInstance)
// isConcatSpreadable: Symbol(Symbol.isConcatSpreadable)
// iterator: Symbol(Symbol.iterator)
// keyFor: ƒ keyFor()
// length: 0
// match: Symbol(Symbol.match)
// matchAll: Symbol(Symbol.matchAll)
// name: "Symbol"
// prototype: Symbol {constructor: ƒ Symbol()
//     description: (...)
//     toString: ƒ toString()
//     valueOf: ƒ valueOf()
//     Symbol(Symbol.toPrimitive): ƒ [Symbol.toPrimitive]()
//     Symbol(Symbol.toStringTag): "Symbol"
//     get description: ƒ description()
//     __proto__: Object
// }
// replace: Symbol(Symbol.replace)
// search: Symbol(Symbol.search)
// species: Symbol(Symbol.species)
// split: Symbol(Symbol.split)
// toPrimitive: Symbol(Symbol.toPrimitive)
// toStringTag: Symbol(Symbol.toStringTag)
// unscopables: Symbol(Symbol.unscopables)

Symbol.for() 接受一个字符串作参数,然后搜索有没有以该参数作为名称的Symbol值。如果有就返回Symbol值,否则返回一个以该字符串为名称的Symbol值
Symbol.keyFor() 返回一个已登记的Symbol类型值的key

const s1 = Symbol.for('foo');
const s2 = Symbol.for('foo');
const s3 = Symbol('foo');
const s4 = Symbol('foo');
console.log(s1 === s2); // true
console.log(s3 === s4); // false
console.log(Symbol.keyFor(s1)); // 'foo'
console.log(Symbol.keyFor(s2)); // 'foo'
console.log(Symbol.keyFor(s3)); // undefined
console.log(Symbol.keyFor(s4)); // undefined

Symbol.prototype.toString() 方法返回当前 symbol 对象的字符串表示。
Symbol.prototype.valueOf() 方法返回当前 symbol 对象所包含的 symbol 原始值。

// console.log(Symbol('foo') + 'bar'); // Uncaught TypeError: Cannot convert a Symbol value to a string
console.log(Symbol('foo').toString() + 'bar'); // Symbol(foo)bar
console.log(Object(Symbol('foo')).toString() + 'bar'); // Symbol(foo)bar
Symbol("desc").toString();   // "Symbol(desc)"
// well-known symbols
Symbol.iterator.toString();  // "Symbol(Symbol.iterator)
// global symbols
Symbol.for("foo").toString() // "Symbol(foo)"

// Object(Symbol("foo")) + "bar";
// TypeError: can't convert symbol object to primitive
// 无法隐式的调用 valueOf() 方法
console.log(Object(Symbol("foo")).valueOf()); // Symbol(foo)
console.log(Symbol("foo").valueOf()); // Symbol(foo)
// console.log(Object(Symbol("foo")).valueOf() + "bar");
// TypeError:  can't convert symbol to string
// 手动调用 valueOf() 方法,虽然转换成了原始值,但 symbol 原始值不能转换为字符串
console.log(Object(Symbol("foo")).toString() + "bar");
// "Symbol(foo)bar",需要手动调用 toString() 方法才行

Symbol.asyncIterator 符号指定了一个对象的默认异步迭代器。如果一个对象设置了这个属性,它就是异步可迭代对象,可用于for await...of循环。

Symbol.hasInstance用于判断某对象是否为某构造器的实例。因此你可以用它自定义instanceof操作符在某个类上的行为。

Symbol.isConcatSpreadable符号等于一个布尔值;用于配置某对象作为Array.prototype.concat()方法的参数时是否展开其数组元素。

Symbol.iterator为每一个对象定义了默认的迭代器。该迭代器可以被for...of循环使用。

Symbol.match指定了匹配的是正则表达式而不是字符串。

Symbol.matchAll返回一个迭代器,该迭代器根据字符串生成正则表达式的匹配项。

Symbol.replace这个属性指定了当一个字符串替换所匹配字符串时所调用的方法。

Symbol.search 指定了一个搜索方法,这个方法接受用户输入的正则表达式,返回该正则表达式在字符串中匹配到的下标。

Symbol.species是个函数值属性,其被构造函数用以创建派生对象。

Symbol.split指向 一个正则表达式的索引处分割字符串的方法。

Symbol.toPrimitive 是一个内置的 Symbol 值,它是作为对象的函数值属性存在的,当一个对象转换为对应的原始值时,会调用此函数。

Symbol.toStringTag 是一个内置 symbol,它通常作为对象的属性键使用,对应的属性值应该为字符串类型,这个字符串用来表示该对象的自定义类型标签,通常只有内置的 Object.prototype.toString() 方法会去读取这个标签并把它包含在自己的返回值里。

Symbol.unscopables 指用于指定对象值,其对象自身和继承的从关联对象的 with 环境绑定中排除的属性名称。

ES6 Symbol

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ES6 Symbol 的相关文章

随机推荐

  • 【AI】《动手学-深度学习-PyTorch版》笔记(二十):图像增强、微调

    AI学习目录汇总 1 图像增强 图像增强可以扩展训练样本数量 减小对某个属性的依赖 比如 裁剪图像 可以减少模型对对象出现位置的依赖 调整亮度 颜色等因素来降低模型对颜色的敏感度等 1 1 准备工作 头文件 matplotlib inlin
  • 01C++11多线程编程之thread,join,detach,joinable以及简说detach传引用地址的大坑

    01C 11多线程编程之thread join detach joinable以及简说detach传引用地址的大坑 1 thread类对象创建线程与join回收线程 1 thread创建线程很简单 定义一个对象然后传一个可调用对象即可 可调
  • Java反射机制【看这一篇就够啦!!!】

    Welcome Huihui s Code World 接下来看看由辉辉所写的关于反射机制的相关操作吧 目录 Welcome Huihui s Code World 一 是什么 二 为什么要使用 三 怎么使用 辉辉小贴士 什么是Class类
  • 数字电路设计之同步电路的一些经验

    在设计的过程中 异步复位电路对硬件要求更低 更容易实现 但是使用同步复位电路却有着诸多优点 使得在实际的工业设计中更多使用的是同步复位电路 使用同步电路一般有以下好处 第一个就是避免毛刺 使用逻辑电路就一定会有毛刺 使用同步电路就有效避免毛
  • Vue生成二维码组件封装

    1 使用方法 1 1 载入 JavaScript 文件 1 2 调用 简单方式 new QRCode document getElementById qrcode your content 设置参数方式 var qrcode new QRC
  • Ubuntu彻底卸载pycharm的方法

    1 查看配置信息位置 首先在解压的pycharm 2020 2 1文件夹中 查看Install Linux tar txt 找到配置信息的位置 下图中蓝色标识 2 卸载安装文件 首先找到安装文件所在的目录 cd 切换至其目录 然后 sudo
  • 深入了解React:组件化开发与状态管理

    简介 React是一个流行的JavaScript库 用于构建用户界面 它以其高效的虚拟DOM和组件化开发的思想而闻名 使得构建复杂的Web应用程序变得更加简单和可维护 本篇博客将带您深入了解React的基本概念 组件化开发和状态管理 帮助您
  • FISCO BCOS(三十六)———Python Sdk window环境部署及应用开发

    1 环境要求 Python环境 python 3 6 3 3 7 3 最好是3 7 3 因为我是 FISCO BCOS节点 可以直接建链 可以是节点前置 也可以是一键部署 2 安装python 2 1 python下载地址 https ww
  • COM 组件设计与应用(十一)

    COM 组件设计与应用 十一 IDispatch 及双接口的调用作者 杨老师 下载源代码一 前言 前段时间 由于工作比较忙 没有能及时地写作 其间收到了很多网友的来信询问和鼓励 在此一并表示感谢 咳 我也需要工作来养家糊口呀 上回书介绍了两
  • linux系统函数总结(一)

    realpath include
  • c陷阱与缺陷

    第一章 词法陷阱 1 这一章没有太多 干货 唯一比较有趣的就是 1 3 语法分析中的 贪心法 所讲内容 这个 贪心 就是编译器会读入字符 如果能新读入的字符和之前所读入字符能组成符号 则编译器会继续读入下一个字符 直到读入的字符不能和之前的
  • BLE MESH组网(五)配置BLE MESH

    BLE MESH 五 配置BLE MESH 前言 概述 配置协议 供应程序 信标 邀请 交换公钥 前言 2017 年 5 月 全球最臭名昭著的勒索软件 WannaCry 在全球范围内积极攻击计算机 劫持用户数据索要赎金 这次攻击影响了 15
  • kafka性能参数和压力测试揭秘

    上一篇文章介绍了Kafka在设计上是如何来保证高时效 大吞吐量的 主要的内容集中在底层原理和架构上 属于理论知识范畴 这次我们站在应用和运维的角度 聊一聊集群到位后要怎么才能最好的配置参数和进行测试性能 Kafka的配置详尽且复杂 想要进行
  • 空间坐标系坐标变换及matlab代码实现

    1 前言 下文中描述坐标系使用了英文的简写 OS Origin Space 原始空间坐标系 NS New Space 新空间坐标系 2 坐标变换介绍 为了解决这个问题 可以利用机器人学中的位姿变换来进行描述 以下依次介绍坐标平移 坐标旋转和
  • j2ee mysql struts_Java新手如何学习Spring、Struts、Hibernate三大框架?

    如何通过java开发培训成为java技术抓紧 这里面java的基础语法很重要 同时 要从基础开始到java的深度编程 这里提炼出一些技术知识点 来避免一些误区 拉勾IT课小编为大家分解 这里面的一些技巧 1 避免使用正则表达式 正则表达式给
  • K8S第三讲 Kubernetes集群配置网络插件

    在Kubernetes集群中 网络插件是必需的 因为它们为Pod提供了可访问的IP地址 并确保它们能够相互通信 Kubernetes支持多种网络插件 包括Calico Flannel Weave Net等 这里以Calico为例介绍如何配置
  • 通过数组下标获取值都有哪些方法_js: 数组

    定义 数组是一种有序数据结合 创建方式 直接量 var a 1 2 构造函数 var b new Array 1 2 注意 构造函数中只传一个参数会变成长度 数组API var arr 0 1 2 push 添加元素 返回length 并把
  • Vue 艺术字体下载、设置

    1 本人常用的下载地址 https zh fonts2u com 2 找到你需要的字体点击下载 3 下载完之后有一个ttf文件 4 在vue里面 我个人在assets文件下创建一个文件夹 叫什么名字都行 找到你下载的ttf文件 把ttf文件
  • 【笔记】c编译执行过程

    c语言 c gt exe 过程 E 预处理 把 h和 c展开形成一个文件 宏定义直接替换 库文件 头文件打开 生成 i文件 gcc E hello c o hello i S 编译 i生成一个汇编代码文件 s gcc S hello i o
  • ES6 Symbol

    概览 const mySymbol Symbol mySymbol console log mySymbol Symbol mySymbol console log mySymbol Symbol mySymbol false consol