JS【详解】Symbol (含Symbol 作为属性名,静态方法for 和 keyFor,11 个内置的 Symbol 值)

ES6 语法,表示唯一且不可变的值,常用作属性键值或者唯一标识符。

let a = Symbol()
let a = Symbol('atomic symbol')console.log(Symbol() === Symbol()) // false
console.log(Symbol('atom') === Symbol('atom')) // false

Symbol 作为属性名

let key = Symbol();
let obj = {[key]: "朝阳",
};
  • Symbol 类型值作为属性名,这个属性不会被for…in遍历到,也不会被Object.keys()Object.getOwnPropertyNames()JSON.stringify()获取到;

  • 可以使用Object.getOwnPropertySymbols方法获取对象的所有symbol类型的属性名;

    const name1 = Symbol("name");
    const obj = {[name1]: "toimc",age: 18
    };
    const SymbolPropNames = Object.getOwnPropertySymbols(obj);
    console.log(SymbolPropNames);
    // [ Symbol(name) ]
    
  • 可以用 ES6 新提供的 Reflect 对象的静态方法Reflect.ownKeys,它可以返回所有类型的属性名:

    console.log(Reflect.ownKeys(obj)); //  ["age", Symbol(name)] 
    

静态方法for 和 keyFor

使用 Symbol.for方法传入字符串,会先检查有没有使用该字符串调用 Symbol.for 方法创建的 symbol 值,如果有,返回该值,如果没有,则使用该字符串新创建一个

const s1 = Symbol("toimc");
const s2 = Symbol("toimc");
const s3 = Symbol.for("toimc");
const s4 = Symbol.for("toimc");console.log(s3 === s4) // true
console.log(s1 === s3) // false

Symbol.keyFor 方法传入一个 symbol 值,返回该值在全局注册的键名:

const sym = Symbol.for("toimc");
console.log(Symbol.keyFor(sym)); // 'toimc'

内置的 Symbol 值

ES6 提供了 11 个内置的 Symbol 值:

Symbol.hasInstance

当其他对象使用 instanceof 判断是否为这个对象的实例时,会调用你定义的这个方法

const obj = {[Symbol.hasInstance](otherObj) {console.log(otherObj);}
};
console.log({ a: "a" } instanceof obj); // false

Symbol.isConcatSpreadable

当一个数组的 Symbol.isConcatSpreadable 设为 true 时,这个数组在数组的 concat 方法中不会被扁平化。

let arr = [1, 2];
console.log([].concat(arr, [3, 4])); // 打印结果为[1, 2, 3, 4],length为4
let arr1 = ["a", "b"];
console.log(arr1[Symbol.isConcatSpreadable]); // undefined
arr1[Symbol.isConcatSpreadable] = false;
console.log(arr1[Symbol.isConcatSpreadable]); // false
console.log([].concat(arr1, [3, 4])); // [ ["a", "b", Symbol(Symbol.isConcatSpreadable): false], 3, 4 ]

Symbol.species

class C extends Array {getName() {return "toimc";}
}
const c = new C(1, 2, 3);
const a = c.map(item => item + 1);
console.log(a); // [2, 3, 4]
console.log(a instanceof C); // true
console.log(a instanceof Array); // true
console.log(a.getName()); // "toimc"

这个例子中,a 是由 c 通过 map 方法衍生出来的,我们也看到了,a 既是 C 的实例,也是 Array 的实例。但是如果我们想只让衍生的数组是 Array 的实例,就需要用 Symbol.species,我们来看下怎么使用:

class C extends Array {// 关键代码:static get [Symbol.species]() {return Array;}getName() {return "toimc";}
}
const c = new C(1, 2, 3);
const a = c.map(item => item + 1);
console.log(a); // [2, 3, 4]
// 这里是false
console.log(a instanceof C); // false
console.log(a instanceof Array); // true
console.log(a.getName()); // error a.getName is not a function

就是给类 C 定义一个静态 get 存取器方法,方法名为 Symbol.species,然后在这个方法中返回要构造衍生数组的构造函数。所以最后我们看到,a instanceof C为 false,也就是 a 不再是 C 的实例,也无法调用继承自 C 的方法。

Symbol.match

当在字符串 str 上调用 match 方法时,会调用这个方法

let obj = {[Symbol.match](string) {return string.length;}
};
console.log("abcde".match(obj)); // 5

Symbol.replace

当在字符串 str 上调用 replace 方法时,会调用这个方法,同上

Symbol.search

当在字符串 str 上调用 search方法时,会调用这个方法,同上

Symbol.split

当在字符串 str 上调用 split 方法时,会调用这个方法,同上

Symbol.iterator

数组的 Symbol.iterator 属性指向该数组的默认遍历器方法:

const arr = [1, 2, 3];
const iterator = arr[Symbol.iterator]();
console.log(iterator);
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

Symbol.toPrimitive

对象的这个属性指向一个方法,当这个对象被转为原始类型值时会调用这个方法。

这个方法有一个参数,即是这个对象被转为的类型,我们来看下:

let obj = {[Symbol.toPrimitive](type) {console.log(type);}
};
// const b = obj++ // number
const a = `abc${obj}`; // string

Symbol.toStringTag

Symbol.toStringTag 和 Symbol.toPrimitive 相似,对象的这个属性的值可以是一个字符串,也可以是一个存取器 get 方法,当在对象上调用 toString 方法时调用这个方法,返回值将作为"[object xxx]"中 xxx 这个值:

let obj = {[Symbol.toStringTag]: "toimc"
};
obj.toString(); // "[object toimc]"
let obj2 = {get [Symbol.toStringTag]() {return "yoyo";}
};
obj2.toString(); // "[object yoyo]"

Symbol.unscopables

这个值和 with 命令有关,但在TS严格模式中,无法使用with。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/34756.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

供应链云仓APP开发:物流行业的数字化转型

在数字化时代,供应链管理正经历着前所未有的变革。供应链云仓APP开发作为这一变革的关键驱动力,为企业提供了一个集成化、智能化的物流解决方案。本文将深入探讨供应链云仓APP开发的重要性、核心功能、开发策略以及它如何助力企业实现物流管理的现代化。…

【JavaScript脚本宇宙】揭开Node.js图像处理的秘密:图像格式转换库

轻松玩转图像处理:从入门到精通 前言 本文将介绍五个用于图像处理的Node.js库,包括Jimp、Sharp、gm、lwip和node-vibrant。这些库提供了各种功能,如图像格式转换、调整大小、裁剪、旋转和主色调提取等。每种库都有其独特的特点和适用场景。…

【独家首发】ONLYOFFICE 8.1:革新办公体验,释放无限创意潜能!

一、全能PDF编辑器:重塑文档管理艺术 官方链接 官方链接:https://www.onlyoffice.com/zh/【点击跳转】 【办公界的变形金刚】ONLYOFFICE 8.1:让文件编辑比变魔术还神奇,一键解锁创意新高度!" 在这个数字化的狂潮中…

百元蓝牙耳机哪款好?值得购买的百元蓝牙耳机品牌有这些

在如今移动互联网时代,蓝牙耳机已经成为不少人生活中的必备产品。然而,市面上的蓝牙耳机种类繁多,价格也参差不齐,选择一款性价比高的产品成了不少消费者的难题。尤其是针对百元左右的蓝牙耳机,更是需要慎重选择。那么…

详解 ClickHouse 的副本机制

一、简介 副本功能只支持 MergeTree Family 的表引擎,参考文档:https://clickhouse.tech/docs/en/engines/table-engines/mergetree-family/replication/ ClickHouse 副本的目的主要是保障数据的高可用性,即使一台 ClickHouse 节点宕机&#…

苹果电脑压缩pdf文件,苹果电脑里如何压缩pdf文件

压缩PDF文件是现代办公和日常生活中经常需要处理的一项任务,无论是为了节省存储空间、方便网络传输,还是为了在移动设备上更流畅地阅读文档,学会有效地压缩PDF都显得尤为重要。在本文中,我们将详细探讨压缩PDF的方法,从…

选型宝典(一)AMD Xilinx 7系列FPGA选型指导

引言introduction Xilinx 7系列FPGA采用28nm工艺,是近年来Xilinx公司推出的一系列高性价比的、应用领域最广泛的可编程逻辑器件。28nm FPGA包含了多个不同的产品线,如Spartan-7、Artix-7、Kintex-7和Virtex-7以及ZYNQ7000。 1、7系列特点概述 Spartan-…

AWS高防贵还是阿里云高防贵

AWS和阿里云作为两大知名云计算服务提供商,都提供了高防护服务,但在价格方面却存在一些差异。本文根据九河云的分析将对AWS和阿里云的高防护服务进行比较,以帮助用户更好地选择适合自己需求的服务。 首先,AWS的高防护服务主要以A…

界面控件DevExpress WinForms启动界面组件,让你的应用更个性化!

DevExpress WinForms的启动界面组件能帮助用户为WinForms应用程序创建令人惊叹的应用启动屏幕、覆盖和等待窗体等。 DevExpress WinForms拥有180组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用…

文本三剑客之首awk

awk 文本三剑客最后一个命令 grep 查 sed 增删改查 主要增和改 awk 按行去列 awk默认的分隔符:空格,tab键,多个空格自动压缩成一个。 awk的工作原理:根据指令信息,逐行的读取文本内容,然后按照条件进…

筛斗数据:数据提取技术,让信息海洋变得有序

在数字化时代,信息如同浩渺的海洋,源源不断地涌入我们的生活和工作。然而,这个信息海洋的浩瀚与繁杂也给我们带来了挑战:如何在海量的数据中快速找到有价值的信息?数据提取技术,作为一种强大的工具&#xf…

内容安全复习 9 - 身份认证系统攻击与防御

文章目录 基于生物特征的身份认证系统概述基于生物特征的身份认证 人脸活体检测检测方法未解决问题 基于生物特征的身份认证系统概述 作用:判别用户的身份、保障信息系统安全。 是识别操作者身份的过程,要保证其物理身份(现实)…

白银价格行情分析兼顾基本面和技术面

许多投资者在进行白银交易时都非常喜欢看技术指标和技术分析。他们浏览不同的网站,看各种各样的白银行情分析信息。网上的白银分析信息网站非常的多,讲解白银交易技巧的书籍也数不胜数,有翻译国外的,也有国人自己编写的。有的讲的…

在线朋友圈系统(Java Web)

本项目是一个基于Java Web技术栈开发的在线朋友圈系统,提供用户注册、登录、动态发布与评论、好友发现与管理等功能。通过Spring Boot、MySQL、MyBatis、Sa-token以及LayUI等技术实现,确保系统具有良好的性能和扩展性。 技术栈 后端技术 Spring Boot: …

全自动搭建定制化深度学习模型

EasyDL 服务自动化生成与部署 EasyDL 定制化训练和服务平台基于百度业界领先算法,旨在为用户量身定制业务专属 AI 模型。通过灵活的配置,用户可以将模型发布为公有云 API、设备端离线 SDK、本地服务器部署包、软硬一体方案等多种输出方式的 AI 服务。目…

html--报销单

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>表格 - 脚本之家</title><style>table{width: 950px;text-align: center;/* 表边框合并 两个单元格之间的边框进行合并 */border-collapse: collapse;margi…

MySQL集群高可用架构之双主双活+keepalived

该教程再linux系统下 从部署单台mysql -->到部署两台双主mysql-->再到安装keepalived-->整体测试 从而实现mysql双主双活高可用的目标。 改文档由本人亲自部署搭建一步一步编写而来&#xff0c;实属不易&#xff0c;如对您有所帮助&#xff0c;请收藏点个赞&#x…

【linux】TCP交流状态变迁及一些函数调用

代码 登录 - Gitee.comhttps://gitee.com/r77683962/linux-6.9.0/commit/50bb00d844b9423c9bacf44d9b06604fab941686 https://gitee.com/r77683962/linux-6.9.0/raw/50bb00d844b9423c9bacf44d9b06604fab941686/dmesg_log/kern_tcp_with_state.log 从打印的日志&#xff0c;…

类的默认成员函数——拷贝构造函数

1.概念引入 在现实生活中&#xff0c;如果有两个兄弟长得一模一样&#xff0c;我们就称其为双胞胎 当我们创建了一个新的对象&#xff0c;需要用同类型的对象拷贝并初始化&#xff0c;就要用到拷贝构造函数 拷贝构造函数&#xff1a;只有单个形参&#xff0c;该形参是对本类类…

mybatis-plus高级功能之实现自定义通用方法

前言 MP在一开始就给大家提供了很多通用的方法&#xff0c;在DefaultSqlInjector这个类中&#xff0c;在MethodList这个集合当中包含的都是通用方法类&#xff0c;如果想要使用自定义通用方法&#xff0c;也需要添加到这个集合当中。 public class DefaultSqlInjector extends…