js高级:es6-es11第五天(模板字符串、Symbol、Set、Map、flat、entries、bigint、FinalizationRegistry、WeakRefs等)

目录

 基础模板字符串的使用

标签模板字符串

展开运算符

数字表示

Symbol

得到对象中的symbol

可以获取描述

Set

Map

字符串填充

尾部逗号

flat

entries

bigint

空值合并运算符

可选链

FinalizationRegistry

WeakRefs

hasOwn


 基础模板字符串的使用

利用``来创建字符串,使用${}插入

  <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,就不用考虑原型的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值