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。

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

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

相关文章

上海展会闭幕RFID技术助力档案管理

上海国际智慧档案展于近日圆满落幕,各参展企业在展会上展示了最新的档案管理技术和解决方案。其中,铨顺宏以其创新的技术和出色的表现,吸引了众多业内人士和观众的关注。 在此次展会上,铨顺宏展示了其全新的RFID智能档案管理。能够…

overlap_filter 学习笔记

overlap_filter overlap_filter 函数的通俗含义是根据给定的掩码(filter_mask),逐层地过滤掉主掩码(mask)中的某些值。具体来说,该函数会从最后一个通道开始,逐层检查并根据对应层的过滤掩码&a…

哈啰集团全面接入通义灵码,AI 生成代码占比 20%,研发提效 12%

6 月 21 日,在阿里云 AI 智领者峰会上海站,哈啰集团算法总监贾立宣布, 哈啰集团已全面接入阿里云通义灵码专属版, 不仅提升了内部研发效率,实现 AI 代码采用率超过 20%,还将灵码接入了哈啰自研 Copilot “海…

【CPP】插入排序:直接插入排序、希尔排序

目录 1.插入排序1.1直接插入排序简介代码分析 1.2直接插入对比冒泡排序简介代码对比分析(直接插入排序与冒泡的复杂度效率区别) 1.3希尔排序简介代码分析 1.插入排序 基本思想:把一个待排数字按照关键码值插入到一个有序序列中,得到一个新的有序序列。 …

“Cannot resolve ch.qos.logback:logback-classic:1.2.3”问题解决办法

当我们添加依赖配置时,通常会遇见如下错误: 这个问题是由于项目中使用了 logback-classic 版本1.2.3,但是无法从当前所配置的仓库中解析到这个特定的版本。可以尝试检查依赖配置,确保指定的仓库中包含了 logback-classic 版本1.2.…

MCU的最佳存储方案CS创世 SD NAND

大家都知道MCU是一种"麻雀"虽小,却"五脏俱全"的主控。它的应用领域非常广泛,小到手机手表,大到航空航天的设备上都会用到MCU.市面上目前几个主流厂商有意法半导体(其中最经典的一款就是STM32系列)…

Android Gradle 使用Task打包APK配置指定输出目录和文件名

想要实现的效果 通过运行Gradle的Task来执行打包操作,无需使用Android Studio的UI操作指定APK文件的输出目录和文件名,需要包含:版本类型,根项目名,打包时间证书不加入版本控制,密码等敏感信息不写入build…

【思科】IPv6 过渡技术 - IPv6 in IPv4隧道

【思科】IPv6 过渡技术 - IPv6 in IPv4隧道 实验要求实现思路IPv6 in IPv4 与 GRE 不同点注意点配置R1基础配置OSPFv3 局域网可达 R2基础配置局域网环境(OSPFv3):IPv6 网络IPv6 in IPv4隧道 R3R4基础配置局域网环境(OSPFv3):IPv6 网络IPv6 in IPv4隧道 R…

【机器学习】——【线性回归模型】——详细【学习路线】

目录 1. 引言 2. 线性回归理论基础 2.1 线性模型概述 2.2 最小二乘法 3. 数学基础 3.1 矩阵运算 3.2 微积分 3.3 统计学 4. 实现与应用 4.1 使用Scikit-learn实现线性回归 4.2 模型评估 5. 深入理解 5.1 多元线性回归 5.2 特征选择 5.3 理解模型内部 6. 实战与项…

【智能算法】人工免疫算法

目录 一、概述 二、人工免疫算法主要特点 2.1自适应性 2.2 鲁棒性 2.3 多样性 2.4 并行性 三、人工免疫算法基本原理 四、人工免疫算法应用领域 五、人工免疫算法matlab代码解析 一、概述 人工免疫算法(Artificial Immune Algorithm,简称AIA)是一种模拟自然界中免疫…

算法学习DAY01

目录 一、算法优劣的核心指标 二、常数时间操作 1、常见的常数时间的操作 2、位运算 &#xff08;1&#xff09;&#xff08;<<&#xff09;左移运算符 &#xff08;2&#xff09;&#xff08;>>&#xff09;右移运算符 &#xff08;3&#xff09;&#xff0…

第27课 原理图的简介

什么是原理图&#xff1f; 原理图就是由元器件连接而成的电路图&#xff0c;它表征了你所设计电路的基本原理。 原理图上的所有元器件&#xff0c;都要从你所画好的元器件符号库中调用。元器件的信息会显示在原理图上&#xff0c;如型号、位号、特性值等。 按照我们的设计&am…

WPF/C#:数据绑定到方法

在WPF Samples中有一个关于数据绑定到方法的Demo&#xff0c;该Demo结构如下&#xff1a; 运行效果如下所示&#xff1a; 来看看是如何实现的。 先来看下MainWindow.xaml中的内容&#xff1a; <Window.Resources><ObjectDataProvider ObjectType"{x:Type local…

【2024.6.25】今日 IT之家精选新闻

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

电线电缆电性能试验方法练习题

一、单选题 1.单、双臂电桥的测量范围,下面哪个符合( )。 A、单臂电桥范围1-99.9Ω B、单臂电桥范围100Ω以上 C、单臂电桥范围1Ω以下 D、根据操作者爱好 参考答案:B 解析:GB/T 3048.4-2007 1 2.根据《电线电缆电性能试验方法第4部分:导体直流电阻试验》GB/T 3048.4…

电源集成:智能真无线耳机设计中的通信接口

真无线耳机&#xff08;TWS 耳机&#xff09;由于电池寿命更长、功能更强大、设计更吸引人以及价格更优惠&#xff0c;因此继续变得更具吸引力。随着耳机制造商专注于小型化和设计改进&#xff0c;并迅速采用功能来增强用户体验&#xff0c;他们能够在强大且竞争激烈的市场中吸…

vue大纲

Vue介绍 Vue是一套用于构建前端用户界面的前端框架 前端开发者主要的工作,就是为了网站的使用者(又称为网站的用户)构建出美观舒适的网页 构建用户界面的传统方式 在传统的web前端开发中,基于jQuery 模板引擎的方式来构建用户界面的 使用vue构建用户界面 使用vue构建用户界面…

提示缺少Microsoft Visual C++ 2019 Redistributable Package (x64)(下载)

下载地址&#xff1a;这个是官网下载地址&#xff1a;Microsoft Visual C 2019 Redistributable Package (x64) 步骤&#xff1a; 第一步&#xff1a;点开链接&#xff0c;找到下图所示的东西 第二步&#xff1a;点击保存下载 第三步&#xff1a;双击运行安装 第四步&#xf…

芒果YOLOv10改进59:主干Backbone篇RepVIT结构:最新重参数化结构 顶会2023 二次改进升级版,最新开源移动端网络架构,速度贼快

💡本篇内容:YOLOv10改进RepVB:最新重参数化结构 顶会2023 二次改进升级版 最新开源移动端网络架构,速度贼快 💡🚀🚀🚀本博客 改进源代码改进 适用于 YOLOv10 按步骤操作运行改进后的代码即可 💡只需订阅这一个专栏即可阅读:芒果YOLOv10所有改进内容 💡本文…

AI大模型企业应用实战(23)-Langchain中的Agents如何实现?

0 前言 这将所有可用的代理按照几个维度进行分类。 预期模型类型 用于聊天模型&#xff08;接收信息&#xff0c;输出信息&#xff09;或 LLM&#xff08;接收字符串&#xff0c;输出字符串&#xff09;。这主要影响所使用的提示策略。 支持聊天历史记录 这些代理类型是否…