ES6之原始数据类型Symbol

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它属于 JavaScript 语言的原生数据类型之一,其他数据类型是:undefinednull、布尔值(Boolean)、字符串(String)、数值(Number)、大整数(BigInt)、对象(Object)。Symbol的作用是创建一个不可变且唯一的标识符,可以用作对象属性的键。它可以用来解决属性名冲突的问题,避免命名冲突。

概述

symbol 是一种基本数据类型。Symbol() 函数会返回 symbol 类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的 symbol 注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:"new Symbol()"。

Symbol的原理是通过调用Symbol函数来创建一个新的Symbol值。每个通过Symbol函数创建的值都是唯一且不可变的。

基本用法

1. 创建一个唯一的属性键:

 
const sym = Symbol();
const obj = {[sym]: 'value'
};
console.log(obj[sym]); // value

2. 使用描述符创建一个带有描述信息的Symbol值:

const sym = Symbol('description');
console.log(sym); // Symbol(description)

3. 使用全局注册表共享Symbol值:

 
const sym1 = Symbol.for('key');
const sym2 = Symbol.for('key');
console.log(sym1 === sym2); // true

4. 获取已注册的全局Symbol键:

const key = Symbol.keyFor(sym1);
console.log(key); // key

5. 遍历对象中所有使用了Symbol作为键名的属性:

const sym = Symbol();
const obj = {[sym]: 'value',foo: 'bar'
};
for (let key in obj) {console.log(key); // foo,不会输出sym
}

6. 使用内置的Well-known Symbols来自定义对象行为:

class MyObject {[Symbol.toStringTag]() {return 'MyObject';}
}
const obj = new MyObject();
console.log(obj.toString()); // [object MyObject]

7. 使用Symbol来定义类的私有属性:

const _privateProperty = Symbol('private');
class MyClass {constructor() {this[_privateProperty] = 'private value';}getPrivateProperty() {return this[_privateProperty];}
}
const myObj = new MyClass();
console.log(myObj.getPrivateProperty()); // private value
console.log(myObj[_privateProperty]); // undefined

这些示例展示了Symbol的一些基本用法,包括创建唯一的属性键、使用描述符创建Symbol值、使用全局注册表共享Symbol值、遍历对象属性、使用Well-known Symbols自定义对象行为以及定义类的私有属性等。这些用法可以帮助我们更好地理解和应用Symbol。

Symbol属性

当使用内置的Symbol属性时,JavaScript引擎会根据这些属性的特定用途来执行相应的操作。下面是对每个示例的用法原理进行解释:

1. Symbol.iterator:

  • 当使用for...of循环遍历一个对象时,JavaScript引擎会查找该对象是否有一个Symbol.iterator方法。
  • 如果存在Symbol.iterator方法,它应该返回一个迭代器对象,该迭代器对象包含next方法。
  • 在每次迭代中,for...of循环会调用迭代器对象的next方法,并将返回的值赋给循环变量。
const obj = {data: ['a', 'b', 'c'],[Symbol.iterator]() {let index = 0return {next: () => {if (index < this.data.length) {return { value: this.data[index++], done: false }} else {return { done: true }}}}}
}
for (let item of obj) {console.log(item) // a, b, c
}

2. Symbol.toStringTag:

  • 当调用对象的toString()方法时,JavaScript引擎会检查该对象是否有一个Symbol.toStringTag属性。
  • 如果存在Symbol.toStringTag属性,它应该是一个字符串值,表示自定义的字符串标签。
  • JavaScript引擎将使用这个标签来构造toString()方法返回的字符串。
const obj = {[Symbol.toStringTag]: 'MyObject',
};
console.log(obj.toString()); // [object MyObject]

3. Symbol.hasInstance:

  • 当使用instanceof操作符检查一个实例是否属于某个类时,JavaScript引擎会查找这个类是否有一个静态方法[Symbol.hasInstance]。
  • 如果存在[Symbol.hasInstance]方法,它应该接受一个参数,并返回一个布尔值表示实例是否属于这个类。
class MyClass {static [Symbol.hasInstance](instance) {return Array.isArray(instance)}
}
console.log([] instanceof MyClass) // true
console.log({} instanceof MyClass) // false

4. Symbol.species:

  • 当在派生类中调用Array原型上的方法(如map、filter等)创建新实例时,JavaScript引擎会查找派生类是否有一个静态属性[Symbol.species]。
  • 如果存在[Symbol.species]属性,它应该是一个构造函数,用于创建新实例。
  • JavaScript引擎将使用[Symbol.species]指定的构造函数来创建新实例,而不是使用派生类本身的构造函数。
class MyArray extends Array {static get [Symbol.species]() {return Array}
}
const arr = new MyArray(1, 2, 3)
const newArr = arr.map((x) => x * 2)
console.log(newArr instanceof MyArray) // false
console.log(newArr instanceof Array) // true

5. Symbol.match、Symbol.replace、Symbol.search和Symbol.split:

  • 当调用字符串的match、replace、search和split方法时,JavaScript引擎会查找传递给这些方法的参数是否有对应的Symbol属性。
  • 如果存在对应的Symbol属性,它应该是一个方法,用于自定义字符串的匹配、替换、搜索和分割逻辑。
  • JavaScript引擎将调用这些自定义方法来执行相应的操作。
class MyMatcher {[Symbol.match](str) {return str.includes('hello');}
}
console.log('hello world'.match(new MyMatcher())); // true

总结

Symbol是ES6中引入的一种新的原始数据类型,用于创建唯一且不可变的标识符。它可以用作对象属性的键,解决属性名冲突的问题。Symbol还可以用于全局注册表、遍历对象属性和使用内置的Well-known Symbols等场景。

使用内置的Symbol属性时,JavaScript引擎会根据这些属性的特定用途来执行相应的操作。每个属性都有特定的行为规范,通过实现这些规范,我们可以自定义对象行为、扩展内置对象功能或实现特定功能。

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

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

相关文章

ELK高级搜索,深度详解ElasticStack技术栈-上篇

前言 1、黑马视频地址&#xff1a;java中级教程-ELK高级搜索&#xff0c;深度详解ElasticStack技术栈 2、本内容仅用于个人学习笔记&#xff0c;如有侵扰&#xff0c;联系删除 1. 课程简介 1.1 课程内容 ELK是包含但不限于Elasticsearch&#xff08;简称es&#xff09;、Lo…

小狐狸ChatGPT付费创作系统V2.3.4独立版 +WEB端+ H5端最新去弹窗授权

ChatGPT付费创作系统V2.3.4版本优化了很多细节&#xff0c;如果使用着2.2.9版本建议没升级的必要。该版本为编译版无开源&#xff0c;2.3.X版本开始官方植入了更多的后门和更隐性的弹窗代码&#xff0c;后门及弹窗处理起来更麻烦。特别针对后台弹窗网址、暗链后门网址全部进行了…

Node.js 的适用场景

目录 前言 适用场景 1. 实时应用 用法 代码 理解 代码示例 理解 3. 微服务架构 用法 代码示例 理解 总结 前言 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境&#xff0c;它使得 JavaScript 可以脱离浏览器运行在服务器端。Node.js 的出现极大地扩展…

git rebase冲突说明(base\remote\local概念说明)

主线日志及修改 $ git log master -p commit 31213fad6150b9899c7e6b27b245aaa69d2fdcff (master) Author: Date: Tue Nov 28 10:19:53 2023 08004diff --git a/123.txt b/123.txt index 294d779..a712711 100644 --- a/123.txtb/123.txt-1,3 1,4 123 4^Mcommit a77b518156…

java使用freemarker模板生成html,再生成pdf

1.freemarker模板生成html 添加Maven依赖 在pom.xml文件中添加以下依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId> </dependency>创建Freemarker…

网络和Linux网络_6(应用层)HTTPS协议(加密解密+中间人攻击+证书)

目录 1. HTTPS协议介绍 1.1 加密解密和秘钥的概念 1. 2 为什么要加密 2. 对称加密和非对称加密 2.1 只使用对称加密 2.2 只使用非对称加密 2.3 双方都使用非对称加密 2.4 使用非对称加密对称加密 2.5 中间人攻击MITM 3. 证书的概念和HTTPS的通信方式 3.1 CA认证机构…

Redis 事件轮询

1 Redis 为什么快 数据存在内存中, 直接操作内存中的数据单线程处理业务请求避免了多线的上下文切换, 锁竞争等弊端使用 IO 多路复用支撑更高的网络请求使用事件驱动模型, 通过事件通知模式, 减少不必要的等待… 这些都是 Redis 快的原因。 但是这些到了代码层面是如何实现的呢…

负载均衡集群 LVS

集群 含义&#xff1a; Cluster、集群、群集多台主机组成一个整体&#xff0c;对外只提供一个访问接口 集群的分类 负载均衡集群&#xff08;LBC&#xff09; 提高系统的响应能力、尽可能处理更多的访问请求、以减少延迟为目标&#xff0c;获得高并发、高负载(LB)的整体性能…

【Linux】系统初始化配置

CentOS 7 的虚拟机安装后必须要做的几个操作&#xff0c;记录以下&#xff0c;网络配置修改、yum源安装、基础工具安装&#xff1a; 1、先修改权限&#xff0c;新建普通用户&#xff0c;并授权普通用户apps 的sudo权限&#xff1b; useradd apps password apps visudo apps A…

基于SSM的论文管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

集合框架(二)LinkedList的常见使用

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍LinkedList的常见使用以及部分理论知识 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主收将持续更新学习记录获&#xff0c;友友们有任何问题可以在评论区留言 目…

【小爱学大数据】一个方法调试了一个上午

为了解决一个棘手的问题&#xff0c;我花了整个上午来调试一个“setBulkFlushInterval”的方法。这个方法的主要作用是控制批量数据刷新的时间间隔&#xff0c;以确保数据的及时性和稳定性。但在面对一个复杂的业务场景时&#xff0c;它却表现得不如预期。 我首先分析了代码逻辑…

Vue2问题:如何全局使用less和sass变量?

前端功能问题系列文章&#xff0c;点击上方合集↑ 序言 大家好&#xff0c;我是大澈&#xff01; 本文约2400字&#xff0c;整篇阅读大约需要4分钟。 本文主要内容分三部分&#xff0c;如果您只需要解决问题&#xff0c;请阅读第一、二部分即可。如果您有更多时间&#xff…

大一学编程怎么学?刚接触编程怎么学习,有没有中文编程开发语言工具?

大一学编程怎么学&#xff1f;刚接触编程怎么学习&#xff0c;有没有中文编程开发语言工具&#xff1f; 1、大一刚开始学编程&#xff0c;面对复杂的代码学习非常吃力&#xff0c;很难入门。建议刚接触编程可以先学习中文编程&#xff0c;了解其中的编程逻辑&#xff0c;学编程…

Flink流批一体计算(22):Flink SQL之单流kafka写入mysql

1. 准备工作 什么是Kafka源表 Kafka是分布式、高吞吐、可扩展的消息队列服务&#xff0c;广泛用于日志收集、监控数据聚合、流式数据处理、在线和离线分析等大数据领域。 docker部署zookeeper docker pull wurstmeister/zookeeperdocker run -d --restartalways \ --log-dr…

LeetCode [中等]3. 无重复字符的最长子串

3. 无重复字符的最长子串 - 力扣&#xff08;LeetCode&#xff09; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 1. 滑动窗口&#xff08;Sliding Window&#xff09;&#xff1a; 滑动窗口是一种用于处理数组或列表的子数组或子序列的问题…

Vue实现纯前端导入excel数据

准备工作 - 下载 xlsx npm install xlsx下面直接上代码&#x1f447; <template><div><input type"file" accept".xlsx, .xls" change"handleClick"></div> </template><script langts setup> import * a…

Vue基础入门(四):Vue3快速开发模板

快速开发Vue的解决方案 ​ Vue 的开发需要的 node 环境&#xff0c;其实上在开发的过程中会遇到一些你想不到的问题&#xff0c;比如 npm工具的版本和 node 环境不匹配&#xff08;你把其他项目导入到自己的环境&#xff09; ​ vue-element-admin&#xff08;是一个官方提供…

git仓库如何撤销提交,恢复提交,重置版本命令

撤销提交&#xff1a; 要撤销最近一次提交&#xff08;未推送到远程仓库&#xff09;&#xff0c;可以使用以下命令&#xff1a; git reset HEAD^该命令将会把最后一次提交的修改从当前主分支中移除&#xff0c;并将这些修改的状态保留在本地工作目录中。 如果想要取消所有的…

HuggingFace学习笔记--利用API实现简单的NLP任务

目录 1--中文分类 1-1--使用预训练模型推理 1-2--基于预训练模型实现下游任务 2--中文填空 3--中文句子关系推断 1--中文分类 1-1--使用预训练模型推理 代码实例&#xff1a; import torch from datasets import load_dataset from transformers import BertTokenizer,…