JavaScript基本对象Symbol研究_01_基本介绍_Symbol构造函数_静态方法_Symbol.for()、Symbol.keyFor()

JavaScript基本对象Symbol研究_01_基本介绍_Symbol构造函数_静态方法_Symbol.for()、Symbol.keyFor()

在ES6(ECMAScript 2015)中,Symbol是一种新的原始数据类型,表示独一无二的值。它是继NumberStringBooleanNullUndefined之后的第七种数据类型。Symbol的引入为对象属性名提供了唯一的标识符,避免属性名的冲突,尤其在对象需要扩展时。

本文将深入探讨Symbol的基本概念、Symbol构造函数以及重要的静态方法Symbol.for()Symbol.keyFor(),帮助您全面理解Symbol在JavaScript中的应用。

一、基本介绍

1. 什么是Symbol?

Symbol是原始数据类型的一种,表示独一无二的值。每个从Symbol()函数返回的Symbol值都是唯一的,即使它们的描述(description)相同。

let sym1 = Symbol('foo');
let sym2 = Symbol('foo');console.log(sym1 === sym2); // 输出: false

2. Symbol的用途

  • 作为对象的唯一属性键:使用Symbol作为对象的属性名,可以确保属性不被意外覆盖或访问。

  • 实现私有属性:通过Symbol,可以模拟对象的私有属性,防止外部直接访问。

  • 元编程Symbol内置了一些预定义的Symbol值(如Symbol.iterator),用于改变语言内部行为,实现迭代器等高级功能。

3. 创建Symbol

创建Symbol值需要调用Symbol()函数,不能使用new关键字,因为Symbol不是构造函数。

let sym = Symbol('description');
  • description(可选):一个字符串,表示对Symbol值的描述,主要用于调试和日志记录。

二、Symbol构造函数

1. 基础语法

let sym = Symbol([description]);
  • description:对Symbol的描述,便于调试。

2. 示例代码

let sym = Symbol('mySymbol');
console.log(sym);               // 输出: Symbol(mySymbol)
console.log(typeof sym);        // 输出: "symbol"

3. 注意事项

  • Symbol值是唯一的:即使描述相同,Symbol值也不相等。

  • Symbol不能与其他类型进行运算Symbol值不能参与算术运算或字符串拼接。

    let sym = Symbol('test');
    console.log(sym + ''); // 报错:Cannot convert a Symbol value to a string
    
  • 转换为字符串:可以使用String()函数或symbol.toString()方法。

    let sym = Symbol('test');
    console.log(String(sym));     // 输出: "Symbol(test)"
    console.log(sym.toString());  // 输出: "Symbol(test)"
    

三、Symbol的使用

1. 作为对象属性名

使用Symbol作为对象的属性名,可以避免属性名的冲突。

let symKey = Symbol('key');
let obj = {[symKey]: 'value'
};console.log(obj[symKey]); // 输出: "value"

2. 定义不可枚举的属性

Symbol属性默认是不可枚举的,不会出现在for...infor...of循环中,也不会被Object.keys()Object.getOwnPropertyNames()返回。

let obj = {};
let sym = Symbol('hidden');obj[sym] = 'secret';for (let key in obj) {console.log(key); // 没有输出
}console.log(Object.keys(obj));                   // 输出: []
console.log(Object.getOwnPropertyNames(obj));    // 输出: []

3. 获取Symbol属性

可以使用Object.getOwnPropertySymbols(obj)获取对象的所有Symbol属性。

let sym1 = Symbol('first');
let sym2 = Symbol('second');
let obj = {[sym1]: 'value1',[sym2]: 'value2'
};let symbols = Object.getOwnPropertySymbols(obj);
console.log(symbols); // 输出: [Symbol(first), Symbol(second)]

四、Symbol的静态方法

1. Symbol.for()

1.1 基础介绍

Symbol.for()方法用于在全局符号注册表中查找或创建一个Symbol。对于相同的键,Symbol.for()会返回相同的Symbol值。

1.2 语法
let sym = Symbol.for(key);
  • key:字符串,表示Symbol的键。
1.3 示例代码
let sym1 = Symbol.for('shared');
let sym2 = Symbol.for('shared');console.log(sym1 === sym2); // 输出: true
1.4 使用场景
  • 跨文件或模块共享Symbol:使用Symbol.for()可以在不同的模块中共享相同的Symbol值。
1.5 注意事项
  • 全局注册表Symbol.for()使用的键在全局范围内有效,可能会导致命名冲突,需要注意键的唯一性。

2. Symbol.keyFor()

2.1 基础介绍

Symbol.keyFor()方法返回一个从全局注册表中找到的Symbol的键。

2.2 语法
let key = Symbol.keyFor(sym);
  • sym:一个通过Symbol.for()注册的Symbol
2.3 示例代码
let sym = Symbol.for('shared');
let key = Symbol.keyFor(sym);console.log(key); // 输出: "shared"
2.4 使用场景
  • 获取全局Symbol的键:在需要根据Symbol值获取其全局键时,可以使用Symbol.keyFor()
2.5 注意事项
  • 仅适用于全局Symbol:对于非全局注册的SymbolSymbol.keyFor()返回undefined

    let localSym = Symbol('local');
    console.log(Symbol.keyFor(localSym)); // 输出: undefined
    

五、示例:Symbol.for()和Symbol()的区别

let localSym1 = Symbol('test');
let localSym2 = Symbol('test');console.log(localSym1 === localSym2); // 输出: falselet globalSym1 = Symbol.for('test');
let globalSym2 = Symbol.for('test');console.log(globalSym1 === globalSym2); // 输出: trueconsole.log(Symbol.keyFor(globalSym1)); // 输出: "test"
console.log(Symbol.keyFor(localSym1));  // 输出: undefined
  • Symbol()创建的Symbol是局部的,每次都会返回新的唯一值。

  • Symbol.for()会在全局注册表中查找,如果存在则返回已注册的Symbol,否则创建新的并注册。

六、Symbol的注意事项

  • 不能使用new关键字Symbol不是构造函数,直接调用即可。

    let sym = new Symbol(); // 报错:Symbol is not a constructor
    
  • Symbol不能被自动转换为字符串:在字符串拼接或其他需要字符串的地方,需要显式转换。

    let sym = Symbol('desc');
    console.log('Symbol is ' + sym); // 报错:Cannot convert a Symbol value to a string// 正确方式
    console.log('Symbol is ' + String(sym)); // 输出: Symbol is Symbol(desc)
    
  • Symbol作为对象属性时的访问:需要使用方括号[],不能使用点.

    let sym = Symbol('key');
    let obj = {[sym]: 'value'
    };console.log(obj[sym]); // 输出: "value"
    

小结

  • 使用Symbol可以创建唯一的值,避免属性名冲突。

  • Symbol()创建的Symbol是局部的,Symbol.for()创建的Symbol是全局注册的。

  • Symbol.keyFor()可以获取全局Symbol的键,对于局部Symbol返回undefined

  • Symbol在对象属性名中的使用需要注意访问方式,使用[]而不是.


参考资料

  • MDN Symbol
  • ECMAScript 2015 标准
  • JavaScript高级程序设计(第4版)

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解Transformer的笔记记录(精简版本)----Seq2Seq → Seq2Seq with Attention

只要是符合类似的框架,都可以统称为 Encoder-Decoder 模型。 1、RNN RNN引入了隐状态h(hidden state)的概念,隐状态h可以对序列形的数据提取特征,接着再转换为输出。 x1,x2,x3,x4如: 自然语言处理问题。x1可以看做是第一个单词,x2可以看做是第二个单词,依次类推语音处…

2024 闽盾杯-黑盾赛道WP

CRYPTO 签到题-学会SM https://www.json.cn/encrypt/sm3 题目要求小写所以需要转换一下 或者脚本: import hashlib message "heidun2024" hash_object hashlib.new(sm3) hash_object.update(message.encode(utf-8)) hash_value hash_object.hexdigest(…

AI助力智慧农田作物病虫害监测,基于YOLOv9全系列【yolov9/t/s/m/c/e】参数模型开发构建花田作物种植场景下棉花作物常见病虫害检测识别系统

智慧农业是一个很大的应用市场,将当下如火如荼的AI模型技术与现实的农业生产场景相结合能够有效提升生产效率,农作物在整个种植周期中有很多工作需要进行,如:浇水、施肥、除草除虫等等,传统的农业作物种植生产管理周期…

带你走近CCV(一)

从事多媒体互动行业8年了,最近才想着自己可以独自写一个识别软件,应该说想把公司里的识别统统临摹一遍,这样在接外包的时候可以游刃有余了 什么是CCV? CCV是一个建立在openCV基础上的一个开源的架构,其全称是Communit…

SpringBoot教程(二十四) | SpringBoot实现分布式定时任务之Quartz(多数据源配置)

SpringBoot教程(二十四) | SpringBoot实现分布式定时任务之Quartz(多数据源配置) 前言多数据源配置引入aop依赖1. properties配置多数据源2. 创建数据源枚举类3. 线程参数配置类4. 数据源动态切换类5. 多数据源配置类HikariCP 版本…

Java基础(2) 之面向对象

文章目录 Java基础(2) 之面向对象1.对象2.类类的注意事项 3.this关键字4.构造器注意 5.封装性6.实体JavaBean实体类 7.成员变量和局部变量的区别8.staticstatic修饰成员变量static修饰成员方法static的注意事项工具类单例设计模式 9.代码块静态代码块实例代码块 10.继承权限修饰…

Springboot——使用poi实现excel动态图片导入解析

文章目录 前言依赖引入导入实现方式一方式二 前言 最近要实现一个导入导出的功能点,需要能将带图片的列表数据导出到excel中,且可以导入带图片的excel列表数据。 考虑到低代码平台的表头与数据的不确定性,技术框架上暂定使用Apache-POI。 …

java 自定义填充excel并导出

首先在resources下面放一个excel模板 1. 方法签名和请求映射 RequestMapping(value "/ExportXls") public ResponseEntity<byte[]> rwzcExportXls(HttpServletRequest request, RequestBody JSONArray jsonArray) throws IOException { RequestMapping(val…

ubuntu 开放 8080 端口快捷命令

文章目录 查看防火墙状态开放 80 端口开放 8080 端口开放 22端口开启防火墙重启防火墙**使用 xhell登录**&#xff1a; 查看防火墙状态 sudo ufw status [sudo] password for crf: Status: inactivesudo ufw enable Firewall is active and enabled on system startup sudo…

微服务实战——登录(普通登录、社交登录、SSO单点登录)

登录 1.1. 用户密码 PostMapping("/login")public String login(UserLoginVo vo, RedirectAttributes redirectAttributes, HttpSession session){R r memberFeignService.login(vo);if(r.getCode() 0){MemberRespVo data r.getData("data", new Type…

进阶功法:SQL 优化指南

目录标题 SQL 优化指南1. 插入数据优化1.1 批量插入数据1.2 手动提交事务1.3 主键顺序插入1.4 大批量插入数据步骤&#xff1a; 2. 主键优化主键设计原则拓展知识 3. ORDER BY 优化3.1 Using filesort3.2 Using index示例 3.3 ORDER BY 优化原则 4. GROUP BY 优化示例 4.1 GROU…

优雅的实现服务调用 -- OpenFeign

文章目录 1. RestTemplate存在问题2. OpenFeign介绍3. 快速上手引入依赖添加注解编写OpenFeign的客户端远程调用 4. OpenFeign参数传递从URL中获取参数传递单个参数传递多个参数传递对象传递JSON 5. 最佳实践Feign继承方式创建一个新的模块引入依赖编写接口打jar包服务实现方实…

javacpp调用pdfium的c++动态库

1、.h头文件 2、生成java代码的conf PdfiumDocumentConfigure.java package org.swdc.pdfium.conf;import org.bytedeco.javacpp.annotation.Platform; import org.bytedeco.javacpp.annotation.Properties; import org.bytedeco.javacpp.tools.InfoMap; import org.byte…

物联网:一种有能力重塑世界的技术

物联网&#xff08;IoT&#xff09;近年来对我们的日常生活产生了如此积极的影响&#xff0c;以至于即使是不懂技术的人也开始相信它所带来的便利以及敏锐的洞察力。 物联网是一场数字技术革命&#xff0c;其意义甚至比工业革命更为重大。物联网是仍处于起步阶段的第四次工业革…

SldWorks问题 2. 矩阵相关接口使用上的失误

问题 在计算三维点在图纸&#xff08;DrawingDoc&#xff09;中的位置时&#xff0c;就是算不对&#xff0c;明明就4、5行代码&#xff0c;怎么看都是很“哇塞”的&#xff0c;毫无问题的。 但结果就是不对。 那就调试一下吧&#xff0c;调试后发现生成的矩阵很不对劲&#…

电力设备图像分割系统源码&数据集分享

电力设备图像分割系统系统源码&#xff06;数据集分享 [yolov8-seg-efficientViT&#xff06;yolov8-seg-C2f-DCNV2等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI G…

分治算法(7)_归并排序_计算右侧小于当前元素的个数

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 分治算法(7)_归并排序_计算右侧小于当前元素的个数 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&…

鸿蒙微内核IPC数据结构

鸿蒙内核IPC数据结构 内核为任务之间的通信提供了多种机制&#xff0c;包含队列、事件、互斥锁、信号量等&#xff0c;其中还有Futex(用户态快速锁)&#xff0c;rwLock(读写锁)&#xff0c;signal(信号)。 队列 队列又称为消息队列&#xff0c;是一种常用于任务间通信的数据…

ASP.NET MVC-懒加载-逐步加载数据库信息

环境&#xff1a; win10, .NET 6.0 目录 问题描述解决方案基础版数据库查询部分&#xff08;Entity Framework&#xff09;控制器前端页面 加载到表格版 问题描述 假设我数据库中有N个表&#xff0c;当我打开某页面时&#xff0c;每个表都先加载一部分&#xff08;比如20条&am…

Chainlit集成Dashscope实现语音交互网页对话AI应用

前言 本篇文章讲解和实战&#xff0c;如何使用Chainlit集成Dashscope实现语音交互网页对话AI应用。实现方案是对接阿里云提供的语音识别SenseVoice大模型接口和语音合成CosyVoice大模型接口使用。针对SenseVoice大模型和CosyVoice大模型&#xff0c;阿里巴巴在github提供的有开…