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函…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...