Symbol
Symbol是ES6新增的一种基本数据类型 它用来表示独一无二的值, 通过Symbol函数生成
Symbol前面不能加new ,创建symbol类型指的时候传入一个参数,这个参数需要是字符串
使用Symbol函数创建一个symbol类型值,可以给它传入一个字符串参数,来对symbol值所一个区分,但是即使多次Symbol函数调用,传入的是相同的字符串,创建的symbol值也是彼此不同的
var s = Symbol('keke')
可转为string或布尔类型的值
s.toString()//Symbol(keke)
Boolean(s)//true
可作为属性名
var s = Symbol()
console.log(s);
let obj = {[s]:'kekek'
}
console.log(obj); //{Symbol(): 'kekek'}
console.log(obj[s]);//keke
访问到Symbol类型的属性名
var s = Symbol("name")
let obj = {[s]: 'kke',age: 12
}
for(var key in obj){console.log(key);//age
}
console.log(Object.keys(obj));//['age']
console.log(Object.getOwnPropertyNames(obj)); //['age']
console.log(JSON.stringify(obj)); //{"age":12}
虽然这么多方法都无法遍历访问到Symbol类型的属性名,但是Symbol类型的属性并不是私有属性,我们可以使用
Object.getOwnPropertySymbols方法获取对象的所有symbol类型的属性名
let SymbolProNames = Object.getOwnPropertySymbols(obj)
console.log(SymbolProNames);//[Symbol(name)]可取到Symbol属性名对应的值
console.log(obj[SymbolProNames[0]]); //kk
除了Object.getOwnPropertySymbols这个方法,还可以用ES6提供的Reflect对象的静态方法 Reflect.ownKeys,它可以返回所有类型的属性名,所以Symbol类型的也会返回
console.log(Reflect.ownKeys(obj));//['age', Symbol(name)]
Symbol.for()和Symbol.keyFor()
Symbol包含两个静态方法 for和keyFor
const s1 = Symbol('pp')
const s2 = Symbol('pp')
const s3 = Symbol.for('pp')
const s4 = Symbol.for('pp')
s1===s2//false
console.log(s3===s4)//true
console.log(s1==s3);//false
- 直接使用Symbol方法,即便传入的字符串是一样的,创建的symbol值也是互不相等的,
- 而使用Symbol.for方法传入字符串会先检查有没有使用该字符串调用Symbol.for方法创建的symbol值,如果有直接返回该值,如果没有,则使用该字符串创建一个。
- 使用该方法创建symbol值后会在全局范围内进行注册。注意:这个注册的范围包括当前页面和页面中包含的iframe,以及service sorker
const iframe = document.createElement('iframe')
iframe.src = String(window.location)
document.body.appendChild(iframe)
iframe.contentWindow.Symbol.for("lison")=== Symbol.for("lison") //true
上面的这段意思是 创建一个iframe节点并把它放到body中,我们通过这个iframe对象的contentWindow拿到这个iframe的window对象
在iframe.contentWindow上添加一个值就相当于你在当前页面定义一个全局变量一样
Symbol.keyFor()
该方法传入一个symbol值,返回该值在全局注册的键名:
const sym = Symbol.for('ook')
console.log(Symbol.keyFor(sym));//ook
11个内置symbol值
Symbol.hasInstance
对象的Symbol.hasInstance 指向一个内部方法 当你给一个对象设置以Symbol.hasInstance为属性名的方法后,
当其他对象使用instanceof 判断是否为这个对象的实例时,会调用你定义的这个方法 参数是其他的这个对象
const obj ={[Symbol.hasInstance](otherObj){console.log(otherObj); //{a: 'a'}}
}
console.log({a:'a'} instanceof obj)//false
instanceof 运算符用于该对象的prototype属性是否出现在某个实例对象的原型链上
- 注意: 在TypeScript中这会报错, instanceof表达式的右侧必须属于类型 “any”,或属于分配给 "Function"接口类型的类型
- 是要求你instanceof操作符右侧的值只能是构造函数或者类 或者类型any类型 这里你可以使用类型断言 将obj改为obj as any
Symbol.isConcatSpreadable
这个值是一个可读写布尔值,当一个数组的Symbol.isConcatSpreadable设置为false时,这个数组在数组的concat方法中不会被扁平化。
let arr = [1,2,3]
console.log([].concat(arr,[4,5]));
let arr1 = ['a','b']
console.log(arr1[Symbol.isConcatSpreadable]);//undefined
arr1[Symbol.isConcatSpreadable] = false
console.log(arr1[Symbol.isConcatSpreadable]);//false
console.log([].concat(arr1,arr));// [ ["a", "b", Symbol(Symbol.isConcatSpreadable): false], 1, 2,3 ]
因为我们设置了Symbol.isConcatSpreadable为false,所以第一个数组没有被扁平化,第一个数组中的 Symbol(Symbol.isConcatSpreadable): false
不是他的元素 而是他的属性 因为数组也是对象,所以也可以给数组设置属性
arr.props = "value"
console.log(arr);//[1, 2, 3, props: 'value']
Symbol.species
使用class定义一个类C, 使用extends继承原生构造函数Array,那么类C创建的实例就能继承所有Array原型对象上的方法,比如map,filter
class C extends Array{getName(){return "Ok"}
}
const c = new C(1,2,3)
console.log(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());//Ok
这个例子中 a是由c通过map方法衍生出来的,我们也看到了 a既是C的实例 也是Array的实例,但是如果只想衍生出的数组是Array的实例
就需要用Symbol.species
class C extends Array{static get[Symbol.species](){return Array}getName(){return "pp"}
}
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);//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、 Symbol.search、Symbol.replace、和Symbol.split
这个Symbol.match值指向一个内部方法 当字符串Str 调用match方法时 ,会调用这个方法
match() 方法检索返回一个字符串匹配正则表达式的结果
let obj = {[Symbol.match](string){return string.length}
}
console.log('abcds'.match(obj));//5
同样的还有Symbol.replace 、 Symbol.search,使用方法和Symbol.match是一样的
Symbol.iterator
数组的Symbol.iterator属性指向该数组的默认遍历器方法
const arr = [1,2,3]
const interator = arr[Symbol.iterator]()
console.log(interator);
console.log(interator.next());//{value: 1, done: false}
console.log(interator.next());//{value: 2, done: false}
console.log(interator.next());//{value: 3, done: false}
这个Symbol.iterator方法是可写的,我们可以自定义遍历器方法
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]:'kkk'}
console.log(obj.toString());//[object kkk]
Symbol.unscopables
这个值和with命令相关 我们先来看with怎么使用
const obj = {a:'a',b:'b'}
with(obj){console.log(a);//aconsole.log(b);//b
}
可以看到 使用with传入一个对象后 在代码块中访问对象的属性就不需要写对象了,直接使用它的属性 对象的Symbol.unscopables
属性指向一个对象,该对象包含了当使用with关键字时,哪些属性被with环境过滤掉
console.log(Array.prototype[Symbol.unscopables]);
{copyWithin: trueentries: truefill: truefind: truefindIndex: trueincludes: truekeys: truevalues: true
}
在Ts中使用Symbol类型
let sym:symbol = Symbol()
unique symbol
ts在2.7版本对Symbol做了补充,增加了 unique symbol这种类型, 他是symbol的子类型 这种类型的值只能由Symbol()活Symbol.for()创建
或者通过指定类型来指定一个值是这种类型 这种类型的值仅可用于常量的定义和用于属性名。另外定义unique symbol类型的值
必须用const 不能let
const key1:unique symbol = Symbol()
let key2:symbol = Symbol()
let obj={[key1]:'value1',[key2]:'value2'
}
console.log(obj[key1]);
console.log(obj[key2]);//error类型symbol不能作为索引类型使用
相关文章:
Symbol
Symbol是ES6新增的一种基本数据类型 它用来表示独一无二的值, 通过Symbol函数生成 Symbol前面不能加new ,创建symbol类型指的时候传入一个参数,这个参数需要是字符串 使用Symbol函数创建一个symbol类型值,可以给它传入一个字符串参数…...
NC65 对上年度反结账,调整数据后重新结账后,对本年度年初重算时系统报错:更新记数错误。
1、对上年度反结账,调整数据后重新结账后,对本年度年初重算时系统报错:更新记数错误。 解决方案: 1、在期初余额节点,按Ctrl+ALT+A重建期初凭证; 2、到结账节点,重建余额表,选择有问题的财务核算账簿,注意:会计期间要放空; 3、到期初余额节点,将刚才删除期初数据的…...

位运算相关
文章目录一、求1的个数二、另类加法三、数组中出现一次的数字四、数组中出现一次的数字变形一、求1的个数 二进制中1的个数 法一:逐位判断 根据与&运算 n&10,说明n的最右边一位为0 n&11,说明n的最右边一位为1 所以思路就是&…...

Linux进程信号(产生、保存、处理)/可重入函数概念/volatile理解/SIGCHLD信号
首先区分一下Linux信号跟进程间通信中的信号量,它们的关系就犹如老婆跟老婆饼一样,没有一毛钱的关系。 信号的概念 信号的概念:信号是进程之间事件异步通知的一种方式,属于软中断。比如:红绿灯是一种信号,…...
锯齿数组 - 贪心
文章目录锯齿数组 -贪心(不过挺像滑动窗口的)1144. 递减元素使数组呈锯齿状锯齿数组 -贪心(不过挺像滑动窗口的) 1144. 递减元素使数组呈锯齿状 题目链接:1144. 递减元素使数组呈锯齿状 题目大意:给你一个…...
[CVPR 2022] Balanced Contrastive Learning for Long-Tailed Visual Recognition
Contents IntroductionMethodPreliminariesBalanced Contrastive Learning (BCL)Drawbacks of SCLClass-averagingClass-complementLower bound of BCLOptimization with Logit CompensationFrameworkExperimentReferencesIntroduction 作者发现对于在长尾数据集上,Supervised…...
23种设计模式-工厂模式
工厂模式是一种创建型设计模式,它提供了一种创建对象的方式,而无需将具体的对象创建逻辑暴露给客户端。在Java中,工厂模式常常用于创建复杂对象或对象的构造过程涉及到多个步骤的情况。 在Android开发中,工厂模式也经常被使用&am…...

Linux操作系统学习(进程等待)
文章目录进程等待进程等待的必要性如何进程等待waiwaitpid验证进程等待 我们知道fork函数可以创建一个子进程,而子进程通常是替父进程完成一些任务,而父进程在fork之后需要通过wait/waitpid等待子进程退出。这就是进程等待 进程等待的必要性 通过获…...
Docker学习(十八)load 和 import 命令的区别
Docker 中有两个命令可以将本地文件系统中的 tar 文件导入到 Docker 中:docker load 和 docker import。尽管它们的作用类似,但它们之间有一些重要的区别。 1.使用方式的不同: docker load 的使用示例: docker load --input tes…...
mysql中的事务
在日常生活中,我们会遇到一个场景,那就是在转账的时候,A有1000块钱,要给B转账500,那么最后的结果是A有500,B有500,但是也有可能出现A没有钱了,B有1000块,或者在转账过程中卡顿,这是不符合逻辑的,那么这个时候就要使用事务来解决问题 事务就是把一堆sql语句打包成一个整体,要么…...
《C++ Primer Plus》第18章:探讨 C++ 新标准(9)
编程练习 下面是一个简短程序的一部分: int main() {using namespace std;// list of double deduced from list contentsauto q average_list ({15.4, 10.7, 9.0});cout << q << endl;// list of int deduced from list contentscout << averag…...

记录一次PWM信号异常问题
问题我使用单片机输出PWM控制机械臂,但是控制过程中,机械臂总是会出现莫名的抽动。利用示波器测试PWM信号,发现信号正常。过程(1)在反复的测试过程中,队友提出,将示波器的地线放在左侧的GND波形…...
简单了解---性能测试
目录 一、什么是性能测试 二、常见的性能测试指标 1、并发 2、响应时间 3、事务 4、点击率 5、吞吐量 6、资源利用率 三、性能测试的分类 1、一般测试 2、负载测试 3、压力测试 4、稳定性测试 四、为什么要做性能测试? 五、影响性能的因素有哪些&…...

1.机器学习笔记第一周
机器学习利用领域: 1:随着网络数据增大,需要搜集用户的数据,做喜好性偏向判断等。 2:只要有数据的,无论是医疗领域,还是基因领域都是需要机器学习来发现数据密码。 3:机器自我学习…...

若依学习(前后端分离版)——启动时发生了啥?(@PostConstruct)(mybatis log free)
我们可以发现若依启动时执行了一些sql我们可以安装一个插件mybatis log free 来更好的进行sql查看 ,安装后需要修改一下若依的日志配置如下查看日志,我们发现执行了三个方法(),分别查询了一些数据。以第二个方法为例子…...
每日十问9c++-内存模型和名称空间
每日十问9c内存模型和名称空间 1.对于下面的情况,应使用哪种存储方案? a.homer 是函数的形参。 b. secret变量由两个文件共享。 c.topsecret 变量由一个文件中的所有函数共享,但对于其他文件来说是隐藏的。 d. beencalled 记录包含它的函数被调用的次数…...

【python】JSON数据类型与Python数据类型之间的转化
注:最后有面试挑战,看看自己掌握了吗 文章目录JSON格式文件JSON格式序列化与反序列化作用JSON常用数据结构键值对的集合值的有序列表JSON数据类型与Python数据类型之间的转化JSON格式和python的区别读写json文件dump 把python 写到json文件load 把json写…...

Spring——什么是事务?传播行为?事务隔离级别有哪些?
思维导图一、什么是事务?多条DML要么同时成功,要么同时失败Transaction(tx)二、事务的四个过程:开启事务(start transaction)执行核心业务代码提交事务(如果核心业务处理过程中没有出…...

【项目实战】使用Feign服务间相互调用,其实OpenFeign也没有想象中那么难嘛
一、Feign介绍 openfeign是一个java的http客户端,用来简化http调用 二、Feign架构(来自官方) Feign由五大部分组成, 由于刚开始接触 feign ,比较关注的 clients 跟 encoders/decoders 三、OKHTTP与Feign之间的关系 在Feign中,Client是一个非常重要的组件,Feign最终…...

tun驱动之ioctl
struct ifreq ifr; ifr.ifr_flags | IFF_TAP | IFF_NO_PI; ioctl(fd, TUNSETIFF, (void *)&ifr); 上面的代码的意思是设置网卡信息,并将tun驱动设置为TAP模式。在TAP模式下,在用户空间下调用open打开/dev/net/tun驱动文件,发送(调用send函…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...

Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
游戏开发中常见的战斗数值英文缩写对照表
游戏开发中常见的战斗数值英文缩写对照表 基础属性(Basic Attributes) 缩写英文全称中文释义常见使用场景HPHit Points / Health Points生命值角色生存状态MPMana Points / Magic Points魔法值技能释放资源SPStamina Points体力值动作消耗资源APAction…...

安全领域新突破:可视化让隐患无处遁形
在安全领域,隐患就像暗处的 “幽灵”,随时可能引发严重事故。传统安全排查手段,常常难以将它们一网打尽。你是否好奇,究竟是什么神奇力量,能让这些潜藏的隐患无所遁形?没错,就是可视化技术。它如…...