当前位置: 首页 > news >正文

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。

相关文章:

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)) // falseSymbol 作为属性名 let key Symbol(); le…...

Vue 项目运行时,报错Error: Cannot find module ‘node:path‘

Vue 项目运行时,报错Error: Cannot find module ‘node:path’ internal/modules/cjs/loader.js:883throw err;^Error: Cannot find module node:path Require stack: - D:\nodejs\node_modules\npm\node_modules\node_modules\npm\lib\cli.js - D:\nodejs\node_mo…...

综合评价 | 基于组合博弈赋权的物流系统综合评价(Matlab)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 综合评价 | 基于组合博弈赋权的物流系统综合评价(Matlab) 组合博弈赋权(Weighted Sum)是一种常见的多目标决策方法,用于将多个目标指标进行综合评估和权衡…...

国标GB28181视频汇聚平台EasyCVR安防监控系统常见播放问题分析及解决方法

国标GB28181安防综合管理系统EasyCVR视频汇聚平台能在复杂的网络环境中,将前端设备统一集中接入与汇聚管理。平台支持多协议接入,包括:国标GB/T 28181协议、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为SDK、宇视…...

30 哈希的应用

位图 概念 题目 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何判断一个数是否在这40亿个整数中 1.遍历,时间复杂度O(N) 2.二分查找,需要先排序,排序(N*logN),二分查找,logN。…...

(笔记)Error: qemu-virgl: Failed to download resource “qemu-virgl--test-image“解决方法

错误: > Downloading https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.2/FD12FLOPPY.zip curl: (22) The requested URL returned error: 404Error: qemu-virgl: Failed to download resource "qemu-virgl--test-image" D…...

IntelliJ IDEA介绍

IntelliJ IDEA 是由 JetBrains 开发的一个集成开发环境 (IDE),专门为 Java 开发设计,同时也支持多种其他编程语言和框架。IntelliJ IDEA 以其智能代码分析、强大的重构功能以及丰富的插件生态系统而闻名,是许多开发者的首选 IDE。 IntelliJ IDEA介绍 IntelliJ IDEA 的主要…...

【office技巧】如何合并pdf并且添加目录页

所用工具:wps,acrobat reader 1.制作目录页 在wps里设置一级标题,二级标题,然后自动生成目录页,保存为pdf。 在acrobat reader里删除除了目录页之外的其他页面。 2.pdf合并 在acrobat reader里合并pdf。 注意有可能…...

Spring Boot中的安全性配置详解

Spring Boot中的安全性配置详解 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将深入探讨如何在Spring Boot应用中实现全面的安全性配置,保…...

数据权限和字段权限设计指南

数据权限和字段权限的设计是信息系统安全的基础。随着数据量的增加和用户需求的多样化,合理的权限设计变得愈加重要。本文将介绍数据权限和字段权限的基本概念、设计思路和实际应用,帮助读者建立全面的权限管理体系。 2. 数据权限设计 2.1 数据权限的定…...

Linux 常用命令之 RZ和SZ 简介

一、引言 在Linux系统管理中,尤其是在远程操作时,文件的上传与下载是常见的需求。对于CentOS用户而言,rz和sz这两个命令提供了简单而高效的文件传输方式,尤其在SSH终端环境中更为便利。本文将详细介绍rz和sz命令的基本概念、如何…...

Docker Compose:简化多容器管理的利器

在现代的应用开发和部署过程中,Docker已经成为不可或缺的工具。它通过容器化技术,使得应用的部署变得更加轻松和高效。然而,当我们需要管理和运行多个容器时,单纯依赖Docker命令行工具可能会显得繁琐且复杂。这时,Dock…...

深度解析:机器学习如何助力GPT-5实现语言理解的飞跃

文章目录 文章前言机器学习在GPT-5中的具体应用模型训练与优化机器翻译与跨语言交流:情感分析与问答系统:集成机器学习功能:文本生成语言理解任务适应 机器学习对GPT-5性能的影响存在的挑战及解决方案技术细节与示例 文章前言 GPT-5是OpenAI公…...

Springcloud-消息总线-Bus

1.消息总线在微服务中的应用 BUS- 消息总线-将消息变更发送给所有的服务节点。 在微服务架构的系统中,通常我们会使用消息代理来构建一个Topic,让所有 服务节点监听这个主题,当生产者向topic中发送变更时,这个主题产生的消息会被…...

js 接收回调函数 转换为promise

下面是一个示例代码,展示如何编写一个接收回调函数并将其转换为 Promise 的 JavaScript 函数: // 定义一个接收回调函数并转换为 Promise 的函数 function convertCallbackToPromise(callbackFunction) {// 返回一个新的 Promise 对象return new Promis…...

Python 面试【★★★】

欢迎莅临我的博客 💝💝💝,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...

计算机网络(物理层)

物理层 物理层最核心的工作内容就是解决比特流在线路上传输的问题 基本概念 何为物理层?笼统的讲,就是传输比特流的。 可以着重看一下物理层主要任务的特性 传输媒体 传输媒体举例: 引导型传输媒体 引导型传输媒体指的是信号通过某种…...

OpenGL-ES 学习(6)---- 立方体绘制

目录 立方体绘制基本原理立方体的顶点坐标和绘制顺序立方体颜色和着色器实现效果和参考代码 立方体绘制基本原理 一个立方体是由8个顶点组成,共6个面,所以绘制立方体本质上就是绘制这6个面共12个三角形 顶点的坐标体系如下图所示,三维坐标…...

《数据结构与算法基础 by王卓老师》学习笔记——类C语言有关操作补充

1.元素类型说明 2.数组定义 3.C语言的内存动态分配 4..C中的参数传递 5.传值方式 6.传地址方式 例子...

高频面试题基本总结回顾2(含笔试高频算法整理)

干货分享,感谢您的阅读! (暂存篇---后续会删除,完整版和持续更新见高频面试题基本总结回顾(含笔试高频算法整理)) 备注:引用请标注出处,同时存在的问题请在相关博客留言…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Selenium常用函数介绍

目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...