什么是Symbol?在实际开发中怎么用?

Symbol 是 ECMAScript 6(ES6)引入的一种新的基本数据类型Symbol 类型的值是唯一不可变的。目的是确保对象属性使用唯一标识符,不会发生属性冲突的危险。

1. 使用Symbol() 创建

调用 Symbol()函数时,也可以传入一个字符串参数作为对符号的描述,将来可以通过这个字符串来调试代码。但是,这个字符串参数与符号定义或标识完全无关。

	let sym1 = Symbol()let sym2 = Symbol('description')console.log(typeof sym1)//symbolconsole.log(sym1)//Symbol()console.log(sym2)//Symbol('description')const s1 = Symbol('foo')const s2 = Symbol('foo')const s3 = Symbol()const s4 = Symbol()console.log(s1 === s2);//falseconsole.log(s3 === s4);//false

注意Symbol()函数不能与 new 关键字一起作为构造函数使用,这样做是为了避免创建包装对象。Symbol 的设计初衷是为了创建唯一的标识符,而不是作为构造函数创建对象。
new Symbol()会导致 TypeError,因为 Symbol 不是构造函数。

 const s1 = new Symbol()// Uncaught TypeError: Symbol is not a constructor

2. 使用 Symbol.for()创建可共享Symbol

Symbol.for 会检查全局 Symbol 注册表,如果存在相同描述的 Symbol,则返回已存在的 Symbol;否则,创建一个新的 Symbol。什么是幂等操作?

    let s1 = Symbol.for('foo'); // 创建新的Symbollet s2 = Symbol.for('foo'); // 通过描述符在全局注册表中获取Symbolconsole.log(s1 === s2); // true

Symbol.for()每个字符串键都执行幂等操作。无论在何处调用 Symbol.for(‘foo’),都会返回相同的全局共享 Symbol。
而每次调用 Symbol() 都会创建一个新的、不共享的 Symbol。即使描述符相同,每次调用Symbol(‘foo’) 都会返回一个不同的 Symbol。

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

3. 在实际开发中的运用

3.1 作为对象属性的键

由于 Symbol 的唯一性,它可以用作对象的属性名,且不容易被意外覆盖。

// 创建一些 Symbol 属性
const symbol1 = Symbol('symbol1');
const symbol2 = Symbol('symbol2');const obj = {[symbol1]: 'value1',[symbol2]: 'value2',
};

3.2 定义常量

使用 Symbol 可以创建全局唯一的常量,避免命名冲突

const LogLevel = {INFO: Symbol('INFO'),WARNING: Symbol('WARNING'),ERROR: Symbol('ERROR')
};function logMessage(message, level = LogLevel.INFO) {// 根据不同的日志级别执行不同的操作if (level === LogLevel.INFO) {console.log(`INFO: ${message}`);} else if (level === LogLevel.WARNING) {console.warn(`WARNING: ${message}`);} else if (level === LogLevel.ERROR) {console.error(`ERROR: ${message}`);}
}logMessage('Something happened', LogLevel.WARNING);

3.3 实现类似私有成员

通过将 Symbol 用作属性名,可以模拟实现类似私有成员的概念。

const privateProperty = Symbol('privateProperty');class MyClass {constructor() {this[privateProperty] = 'I am private!';}getPrivateProperty() {return this[privateProperty];}
}const instance = new MyClass();
console.log(instance.getPrivateProperty()); // 输出:I am private!
console.log(instance[privateProperty]); // undefined,无法直接访问私有属性

3.4 使用内置 Symbol 值

JavaScript 提供了一些内置的 Symbol 值,例如 Symbol.iteratorSymbol.toPrimitive 等,它们用于定义对象的默认迭代行为、类型转换等。
拿Symbol.iterator 举个栗子:
它是一个内置的 Symbol 值,它用于定义对象的默认迭代器
迭代器是一个对象,它实现了一个 next方法,该方法返回包含 valuedone 属性的对象,value 表示当前迭代的值,done属性表示迭代是否完成。

const myObject = {values: [1, 2, 3],[Symbol.iterator]: function () {let index = 0;const values = this.values;return {next: function () {return index < values.length ?{ value: values[index++], done: false }:{ value: undefined, done: true };}};}
};for (const value of myObject) {console.log(value);
}

4. Symbol的遍历

注意:Symbol 是不可被枚举的,因此使用 for...in循环或 Object.keys() 无法遍历出 Symbol 属性。
Object.getOwnPropertySymbols(obj),可以获取所Symbol 属性值, 返回值是一个数组。

    const symbol1 = Symbol('symbol1');const symbol2 = Symbol('symbol2');const obj = {[symbol1]: 'value1',[symbol2]: 'value2',greeting: 'hello'};// 获取对象的所有 Symbol 属性const symbolProperties = Object.getOwnPropertySymbols(obj);console.log(symbolProperties);// [Symbol(symbol1), Symbol(symbol2)]console.log(Object.keys(obj));// ['greeting']

Reflect.ownKeys(obj),可以获取包含 Symbol在内的所有键。

    // 获取包含 Symbol的所有键const allKeys = Reflect.ownKeys(obj);console.log(allKeys);//[Symbol(symbol1), Symbol(symbol2),'greeting']

同样,也可以使用Object.keysObject.getOwnPropertySymbols的组合的数组。

    const allKeys = [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];console.log(allKeys);

JavaScript高级知识点:
1.什么是闭包和作用域链?
2.什么是arguments对象?
3.什么是proxy代理?
4.类数组对象是什么?
5.Array.from()的6种常见用法

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

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

相关文章

ubuntu docker镜像制作及常用命令

ubuntu docker镜像制作及常用命令 一、安装docker 1、安装 sudo apt install docker.io 2、拉取ubuntu镜像 sudo docker pull ubuntu:18.04 3、从Dockerfile构建镜像 3.1、 Dockerfile示例 FROM ubuntu:18.04MAINTAINER [user] [email]RUN apt-get update \&& …

.NET 自定义中间件 判断是否存在 AllowAnonymousAttribute 特性 来判断是否需要身份验证

public Task InvokeAsync(HttpContext context){// 获取终点路由特性var endpointFeature context.Features.Get<IEndpointFeature>();// 获取是否定义了特性var attribute endpointFeature?.Endpoint?.Metadata?.GetMetadata<AllowAnonymousAttribute>();if …

CentOS 7部署vsftpd

&#xff08;1&#xff09;概述 vsftpd是Linux上一个非常流行的FTP服务器软件。它使用简单&#xff0c;功能强大&#xff0c;安全性高。本文将介绍如何在CentOS 7上部署vsftpd服务器。 &#xff08;2&#xff09;安装vsftpd 使用yum命令安装vsftpd&#xff1a; yum install…

二叉树题目:二叉树着色游戏

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;二叉树着色游戏 出处&#xff1a;1145. 二叉树着色游戏 难度 6 级 题目描述 要求 两位玩家参与二叉树着色游戏。给定二叉树的根结点 root \textt…

【稳定检索|投稿优惠】2024年公共服务、健康与医药国际会议(ICPSHM 2024)

2024年公共服务、健康与医药国际会议(ICPSHM 2024) 2024 International Conference on Public Services, Health, and Medicine(ICPSHM) 一、【会议简介】 ​2024年公共服务、健康与医药国际会议&#xff08;ICPSHM 2024&#xff09;将于三亚这片美丽的海滨城市盛大召开。我们诚…

送货服务Grupo RÃO将在Moonbeam上通过DUX推出Web3支持的忠诚度计划

波卡上的首选多链开发平台Moonbeam宣布使用由Account Abstraction提供支持的DUX智能钱包为Grupo RO推出Web3忠诚度计划。此次合作为Grupo RO食品配送服务带来了新的奖励计划&#xff0c;其中包括折扣、产品、优惠券、竞赛等福利的订阅 — 所有这些都得益于Moonbeam的区块链技术…

UDP特性之组播(多播)

UDP特性之组播 1. 组播的特点2. 设置主播属性2.1 发送端2.2 接收端 3. 组播通信流程3.1 发送端3.2 接收端 4. 通信代码 原文链接 在公司测试广播和多播有一点问题。。。 1. 组播的特点 组播也可以称之为多播这也是UDP的特性之一。组播是主机间一对多的通讯模式&#xff0c;是…

URP管线下Shader中的SubShader Tags、Pass Tags、ShaderLab Commands总结

一、SubShader Tags SubShader Tags是提供SubShader信息的键值对&#xff0c;它们允许你指定特定的设置好让渲染管线知道如何处理SubShader。 下面分别介绍一下SubShader中的tag。 1、 RenderPipeline 这个tag用来指定SubShader的目标渲染管线&#xff0c;不同的渲染管线有特定…

Vue3源码梳理:运行时之基于h函数生成vnode的内部流程

VNode 节点类型 对于vnode而言&#xff0c;具备很多节点类型vue源码中patch函数switch处理包含了好几种类型&#xff0c;常见类型如下 Text&#xff1a;文本节点Comment&#xff1a;注释节点Static&#xff1a;静态dom节点Fragment&#xff1a;包含多个根节点的模板被表示为一…

SHT10温湿度传感器——STM32驱动

———————实验效果——————— &#x1f384;硬件外观 &#x1f384;接线 &#x1f388; 3.3V供电 &#x1f388; IIC通讯 &#x1f384; 代码获取 &#x1f388; 查看下方 ———————END———————

FB使用汇编模拟GoSub(子函数)功能

在FB里不支持GoSub功能&#xff0c;在面对函数内简单又重复的操作&#xff0c;而所涉及变量又比较多的时候&#xff0c;再在外边定义一个函数就显得累赘&#xff0c;此时如果可以有一个函数内部的子函数&#xff0c;就显得方便多了。 在汇编探索里发现&#xff0c;可以使用汇编…

20231218在微软官网下载WINDOWS10以及通过rufus-4.3p写入U盘作为安装盘

20231218在微软官网下载WINDOWS10以及通过rufus-4.3p写入U盘作为安装盘 2023/12/18 17:06 百度搜索&#xff1a;下载 windows10 https://www.microsoft.com/zh-cn/software-download/windows10 下载 Windows 10 更新之前&#xff0c;请参阅 Windows 版本信息状态中的已知问题&a…

企业要想成功就必须培养“支持说真话的文化”

大家好&#xff0c;欢迎来到我的博客。今天&#xff0c;我想和大家谈谈企业文化的重要性&#xff0c;特别是支持说真话的文化。 1. 为什么说真话很重要&#xff1f; 在当今社会&#xff0c;说真话似乎越来越难了。我们害怕得罪别人&#xff0c;害怕被孤立&#xff0c;害怕被认…

系统设计——系统安全

HTTPS 是如何工作的&#xff1f; 安全超文本传输​​协议&#xff08;HTTPS&#xff09;是超文本传输​​协议&#xff08;HTTP&#xff09;的扩展。HTTPS 使用传输层安全性&#xff08;TLS&#xff09;传输加密数据。如果数据在网上被劫持&#xff0c;劫持者得到的只是二进制…

php去掉数组的key,重组数组的方法

php去掉数组的key&#xff0c;重组数组的方法 方法一&#xff1a;foreach循环方法二&#xff1a;array_values()函数方法三&#xff1a;array_map()函数方法四&#xff1a;强制类型转换 方法一&#xff1a;foreach循环 使用foreach循环遍历数组时&#xff0c;可以只取出数组的…

TaxtArea中内嵌一张放松图片,该图片实现属性悬浮放大功能

TaxtArea中内嵌一张发送图片&#xff0c;该图片实现属性悬浮放大功能&#xff0c;离开还原效果&#xff0c;点击发送按钮后&#xff0c;发送图片变为loading&#xff0c; <div class"textarea-wrapper" ><a-textarearef"textArea"v-model.trim&q…

汇编语言学习(3)

更好的阅读体验&#xff0c;请点击 YinKai s Blog 。 内存段 ​ 上面讨论的汇编程序的三个部分&#xff0c;也代码各种内存段。 ​ 有趣的是&#xff0c;如果将 section 关键字替换为 segment&#xff0c;将会得到相同的结果&#xff0c;这是因为对于汇编器而言&#xff0c;这…

web应用开发技术的一些概念

一、Servlet 1.Servlet的工作过程&#xff1a; Servelt的工作流程示意图 &#xff08;1&#xff09;客户端发起一个Http请求到服务器&#xff0c;请求特定的资源或者是要执行特定的操作 &#xff08;2&#xff09;服务器在接收到请求后&#xff0c;根据请求相应的URL将请求分发…

PostgreSQL进阶操作

PostgreSQL进阶操作 SQL执行顺序 (9) SELECT (10) DISTINCT col1, [OVER()] (6) AGG_FUNC(col2) (1) FROM table1 (3) JOIN table2 (2) ON table1.col table2.col (4) WHERE constraint_expression (5) GROUP BY col (7) WITH CUBE|ROLLUP (8) HAVING constraint_expression…

21、同济、微软亚研院、西安电子科技大提出HPT:层次化提示调优,独属于提示学习的[安妮海瑟薇]

前言&#xff1a; 本论文由同济大学、微软亚洲研究院、西安电子科技大学&#xff0c;于2023年12月11日中了AAAI2024 论文&#xff1a; 《Learning Hierarchical Prompt with Structured Linguistic Knowledge for Vision-Language Models》 地址&#xff1a; [2312.06323]…