JS中的【Symbol】全面讲解

2024-09-06 07:12
文章标签 讲解 全面 js symbol

本文主要是介绍JS中的【Symbol】全面讲解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 什么是 Symbol?

Symbol 是 ES6 引入的一种新的原始数据类型(Primitive Data Type)。与 stringnumberbooleannullundefined 一样,Symbol 是不可变的原始值。Symbol 的特殊之处在于它是唯一的,即使两个 Symbol 的描述相同,它们的值也不相等。

2. Symbol 的创建

Symbol 通过 Symbol() 函数创建,可以接受一个可选的字符串参数作为描述(description),用于调试或日志记录,但不影响 Symbol 的唯一性。

let sym1 = Symbol();
let sym2 = Symbol('foo');
let sym3 = Symbol('foo');console.log(sym2 === sym3); // false
3. Symbol 的用途
  • 作为对象属性的键(Key): Symbol 最常见的用途之一是用作对象的属性键。由于每个 Symbol 都是唯一的,因此它可以确保属性不被意外覆盖或冲突。
let mySymbol = Symbol('myKey');
let obj = {};obj[mySymbol] = 'value';
console.log(obj[mySymbol]); // 'value'
  • 防止对象属性名冲突: 使用 Symbol 作为对象属性名可以避免在大型代码库或库之间发生属性名冲突。

  • 实现迭代器(Iterators): Symbol.iterator 是内置的 Symbol,用于定义对象的默认迭代器。当对象使用 for...of 循环遍历时会调用这个方法。

let iterable = {[Symbol.iterator]() {let step = 0;return {next() {step++;if (step <= 5) {return { value: step, done: false };}return { value: undefined, done: true };}};}
};for (let value of iterable) {console.log(value); // 1, 2, 3, 4, 5
}
  • 元编程和反射(Reflection): Symbol 还可以用来定义对象行为的某些方面,比如 Symbol.toPrimitiveSymbol.toStringTag 等,这些 Symbol 可以自定义对象的原生行为。
let obj = {[Symbol.toPrimitive](hint) {if (hint === 'number') {return 10;}return null;}
};console.log(+obj); // 10
4. 内置 Symbol

JavaScript 提供了一些内置的 Symbol,用于语言的内部机制。常见的内置 Symbol 包括:

  • Symbol.iterator:定义对象的默认迭代器。
  • Symbol.toPrimitive:对象转换为原始类型时调用的函数。
  • Symbol.toStringTag:修改 Object.prototype.toString() 的返回值。
  • Symbol.hasInstance:自定义 instanceof 操作符的行为。
  • Symbol.isConcatSpreadable:自定义数组 concat 方法是否展开对象。
class MyArray extends Array {static get [Symbol.species]() {return Array;}
}let myArray = new MyArray(1, 2, 3);
let mappedArray = myArray.map(x => x * x);console.log(mappedArray instanceof MyArray); // false
console.log(mappedArray instanceof Array);   // true
5. Symbol 的局限性
  • Symbol 无法被隐式转换为字符串或数字:使用 Symbol 作为字符串连接或数字运算时会抛出错误。这是为了防止意外的类型转换。
let sym = Symbol('foo');
console.log('Symbol is ' + sym); // TypeError: Cannot convert a Symbol value to a string
  • Symbol 的枚举性:使用 for...inObject.keys() 遍历对象时,Symbol 属性是不可枚举的,但可以使用 Object.getOwnPropertySymbols() 来获取对象的 Symbol 属性。
let obj = {[Symbol('key')]: 'value'
};console.log(Object.keys(obj)); // []
console.log(Object.getOwnPropertySymbols(obj)); // [ Symbol(key) ]
  • Global Symbol 注册表:通过 Symbol.for()Symbol.keyFor() 可以使用全局的 Symbol 注册表,这允许你跨文件或模块共享 Symbol。
let globalSym = Symbol.for('globalKey');
let globalSym2 = Symbol.for('globalKey');console.log(globalSym === globalSym2); // true
console.log(Symbol.keyFor(globalSym)); // 'globalKey'
6. Symbol 的实际应用场景
  • 框架和库中避免命名冲突: 当开发公共库或框架时,可以使用 Symbol 作为内部属性键,避免用户代码中的命名冲突。
  • 实现私有属性: 尽管 Symbol 不是完全私有的,但它可以作为一种模拟私有属性的手段,避免直接通过常规方法访问这些属性。
  • 自定义对象行为: 使用内置 Symbol 可以让对象表现出更符合预期的行为,如自定义对象的字符串表示、数值转换等。

总结来说,Symbol 是 JavaScript 中强大且灵活的工具,提供了许多高级功能,如安全的对象属性定义和元编程能力。掌握 Symbol 有助于编写更加健壮和可扩展的代码。

这篇关于JS中的【Symbol】全面讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1141357

相关文章

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

C++ vector的常见用法超详细讲解

《C++vector的常见用法超详细讲解》:本文主要介绍C++vector的常见用法,包括C++中vector容器的定义、初始化方法、访问元素、常用函数及其时间复杂度,通过代码介绍的非常详细,... 目录1、vector的定义2、vector常用初始化方法1、使编程用花括号直接赋值2、使用圆括号赋值3、ve

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Python基础文件操作方法超详细讲解(详解版)

《Python基础文件操作方法超详细讲解(详解版)》文件就是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位,文件的核心操作就是读和写,:本文主要介绍Python基础文件操作方法超详细讲解的相... 目录一、文件操作1. 文件打开与关闭1.1 打开文件1.2 关闭文件2. 访问模式及说明二、文件读写1.

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

C++快速排序超详细讲解

《C++快速排序超详细讲解》快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下... 目录一、快速排序原理二、快速排序标准代码三、代码解析四、使用while循环的快速排序1.代码代码1.由快