目录
基础模板字符串的使用
利用``来创建字符串,使用${}插入
<script>
let name = 'aaa'
let age = 14
let ifo = `my name is ${name},age is ${age}`//my name is aaa,age is 14
console.log(ifo);
</script>
标签模板字符串
let name = 'aaa'
let age = 14
function fn(...args){
console.log(args);
}
fn`my name is ${name},age is ${age}`
第一个是普通的数组,放入被分割之后的字符串,后面的参数就是调用的字符串
展开运算符
const aaa = [123,'ooo',234,'oio']
const bbb = 'hello'
function foo(a,b,...c){
console.log(a,b,c);
}
foo(...aaa)
foo(...bbb)
也就是说...可以将字符串或者数组拆开
对于对象,在构建对象字面量的时候可以使用,但是不能像上面那样传入函数
const obj = {
name : 111,
age :12
}
function foo(a,b,...c){
console.log(a,b,c);
}
//foo(...obj)这是不允许的
const obj1 ={
...obj,
sex:1
}
console.log(obj1);
数字表示
//二进制
console.log(0b100);
//8进制
console.log(0o100);
//16进制
console.log(0x100);
输出还是按照十进制来的
长数字,用下划线分割
const bignum = 100_000_212_221
console.log(bignum);
Symbol
也是基本数据类型
比如
const obj = {
fn:111
}
function foo(obj){
obj.fn = function(){
}
}
foo(obj)
当我带入函数时,我其实是想添加新的属性fn,但是我不能确定原本的obj中是否有fn属性
symbol就是为了解决这种问题,为了创造一个独一无二的值
symbol可以作为对象的key
const ss = Symbol()
const obj1 = {
ss:111,
[ss]:1222
}
console.log(obj1);
这样是不会冲突的
之前的函数可以改为:
const obj = {
fn:111
}
function foo(obj){
const fn = Symbol
obj[fn] = function(){
}
}
foo(obj)
console.log(obj);
这样就不会冲突了
得到对象中的symbol
const s1 = Symbol()
const obj = {
age :111,
[s1]:222,
name :000
}
console.log(Object.keys(obj));
只会得到age name
可以采用下面的方法得到symbol里面的值
const s1 = Symbol()
const s2 = Symbol()
const obj = {
age :111,
[s1]:222,
[s2]:2122,
name :000
}
console.log(Object.getOwnPropertySymbols(obj));
for(let i of Object.getOwnPropertySymbols(obj)){
console.log(i);//只能输出symbol,不能输出s1 s2
console.log(obj[i]);// 222 2122
}
symbol在创建的时候可以传入description
const s3 = Symbol('ccc')
console.log(s3.description);
可以利用这个创造两个相同的symbol
const s3 = Symbol('ccc')
console.log(s3.description);
const s4 =Symbol.for(s3.description)
const s5 =Symbol.for(s3.description)
console.log(s4 === s5);//true
这个用的不多 很特殊的情况才会用
可以获取描述
console.log(Symbol.keyFor(s4));//ccc
Set
这两个都是新的数据结构
set是集合
基本调用
const s = new Set()
s.add(123)
s.add(2828)
s.add(2828)
console.log(s);//123,2828
数组去重
const old = [123,123,222,222,333,333]
//数组去重
const new1 =new Set(old)
const newarray = Array.from(new1)
console.log(newarray);
其他方法
WeakSet
weakset只能放对象类型,对所有对象的引用都是弱引用
也就是时候其引用的对象 有可能在后期被销毁,所以不能遍历
这个用的不多
Map
表示一种映射关系,跟对象很类似
如果我们想要使用对象作为key,例如
const ss = {name :12}
const ss1 = {age:22}
const obj ={
[ss]:2222,
[ss1]:2121
}
console.log(obj);
但是这样不是将对象作为的key,只是把对象转换为了字符串,所以最后打印结果只有一个映射关系
使用map就可以
const mapp = new Map()
mapp.set(ss,'aaaa')
mapp.set(ss1,2322)
console.log(mapp);
WeakMap
key只能为对象对所有对象的引用都是弱引用,跟weakset类似
字符串填充
padstart(a,b),向前填充,一共长度为a,填充为b
padend向后填充
const ss = '1'.padStart(3,'0')
const ss1 = '1'.padEnd(3,'0')
console.log(ss);//001
console.log(ss1);//100
应用,敏感信息遮盖
const ss = '12345678901234'
const slicess = ss.slice(-4);
console.log(slicess.padStart(ss.length,'*'));
尾部逗号
就是可以在参数末尾加逗号
function fn(a,b,){
}
flat
例子
const ss = [1,2,3,4,[2,3],[2,4],[[2,3],[6,7]]]
console.log(ss.flat(1));//[1, 2, 3, 4, 2, 3, 2, 4, Array(2), Array(2)]
console.log(ss.flat(2));//[1, 2, 3, 4, 2, 3, 2, 4, 2, 3, 6, 7]
将数组在n维上平坦化
flatMap()
const aa = ['aaa bbb ccc','ddd eee fff','ggg hhh mmm']
const bb = aa.map(item =>item.split(' '));
const cc = bb.flat(1)
console.log(cc);//['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg', 'hhh', 'mmm']
const dd = aa.flatMap(item =>item.split(' '))
console.log(dd);//和上面一样
entries
将对象转换为数组
const obj = {
name:123,
age:222
}
const sss =Object.entries(obj)//[['name', 123],['age', 222]]
const sss1 =Object.fromEntries(sss)
bigint
在很大的值后面加n 以确保其准确性
console.log(Number.MAX_SAFE_INTEGER);//9007199254740991
const bigg = 9007199254740996n
console.log(bigg);//9007199254740996n
但是如果要运算,都必须加n
console.log(bigg-100000n)
空值合并运算符
obj?.fn?.run()
function fn(aa){
aa = aa??'默认'
console.log(aa);
}
fn()//默认
fn(null)//默认
fn(0)//0
当aa是未定义undefined或者null,就赋予 默认,否则保持原值
可选链
对于
const obj ={
fn:{
run:function(){
console.log(111);
}
}
}
if(obj.fn && obj.fn.run){
obj.fn.run()
}
加if判断的原因是,经常这个obj有没有那些属性和方法我们是不知道的,为了防止报错就用if判断一下
现在可以更简洁
obj?.fn?.run?.()
FinalizationRegistry
也就是说,当对象被垃圾回收时,调用函数
let obj = {
name:123
}
const final = new FinalizationRegistry(()=>{
console.log('aaaa');
})
final.register(obj)//aaaa
obj= null
运行程序,过一会打印aaaa
也可以同时注册多个对象,且可以传入参数以区分是哪个对象被销毁。register里面的第二个参数就是函数参数value
let obj = {
name:123
}
let obj1 = {
age:23
}
const final = new FinalizationRegistry((value)=>{
console.log('aaaa'+value);
})
final.register(obj,'obj')//aaaaobj
final.register(obj1,'obj1')//aaaaobj1
obj= null
obj1= null
WeakRefs
先看一个 例子
let obj = {
name:123
}
let obj1 = obj
const final = new FinalizationRegistry((value)=>{
console.log('aaaa'+value);
})
final.register(obj,'obj')//没有输出
obj= null
这个时候没有输出,因为obj1对obj的内容是强引用,尽管将obj设置为null,由于obj1强引用的存在,不会将其回收
但是有的时候我们不希望这样,我们定义obj1只是暂时使用一下obj内部的内容
所以可以使用WeakRefs
let obj = {
name:123
}
let obj1 = new WeakRef(obj)
const final = new FinalizationRegistry((value)=>{
console.log('aaaa'+value);
})
final.register(obj,'obj')//aaaaobj
console.log(obj1.deref().name);//123
obj= null
相当于这里 obj1.deref().name,先给obj做解构再调用name
注意这里不能写const obj2 = obj1.deref(),因为这样写又会生成强引用
有一说一我觉得这个东西似乎比较鸡肋
hasOwn
为了确定对象中是否有某种方法或者属性,可以使用
hasOwnProperty
let obj = {
name:123,
}
obj.__proto__.sing = function(){
}
console.log(obj.hasOwnProperty('name'));//true
console.log(obj.hasOwnProperty('sing'));//false
obj.__proto__ = null
console.log(obj.hasOwnProperty('name'));//报错
console.log(Object.hasOwn(obj,'name'));//true
但是obj自己只是一个对象,没有这个方法,当使用他时必须去原型中去找,但是如果这个是其原型是null就不能使用这个方法了
可以使用Object.hasOwn,就不用考虑原型的问题