ES~ES11复习

ES6

let

let声明的变量不能重复声明,只在当前作用域有效,不存在变量提升,虽然let声明的是块级作用域,但是并不影响作用域链

const

const声明一般必须要赋值,声明后常量就不可更改,声明也是块级作用域,const对于声明数组和对象的变量,修改数组和对象不算对常量的更改

解构赋值

按照一定模式从数组和对象中提取值,对变量进行赋值

数组解构

解构赋值都是一一对应的,按照顺序

const F4=['小沈阳','刘能','孙红雷','宋小宝']
let [xiao,liu,sun,song]=F4
console.log(xiao,liu,zhao,song)

也可以取某一个项的值(结构必须一致)

const F4=['小沈阳','刘能','孙红雷','宋小宝']
let [,,sun,]=F4
console.log(sun)//孙红雷

还可以使用扩展运算符提取(只能写在最后)

const F4=['小沈阳','刘能','孙红雷','宋小宝']
let [xiao,liu,...all]=F4
console.log(all)//['孙红雷','宋小宝'] 返回一个包含最后所有内容的数组

如果提取长度小于数组长度,则提取按照前后顺序进行

const F4=['小沈阳','刘能','孙红雷','宋小宝']
let [xiao,liu]=F4
console.log(xiao,liu)//小沈阳 刘能

如果提取长度大于数组长度,则提取的最后结果是undefined

const arr=[100,200]
let [a,b,c]=arr
console.log(c)//undefined

对象解构

对象解构和数组结构类似,不过对象解构是根据对象的属性名来进行取值的

const obj={
    name:'小明',
    age:30,
    say(){
        console.log(name+'今年'+age+'岁了')
    }
}
let {name,say}=obj
console.log(name)//小明
say()//小明今年30岁了

如果解构出来的变量名与外边的变量名重复,就需要重新命名

const name='小花'
const sya=function(){console.log('我饿了')}
const obj={
    name:'小明',
    age:30,
    say(){
        console.log(name+'今年'+age+'岁了')
    }
}
let {name:nameObj,age,sayXiao}=obj
console.log(nameObj)//小明
sayXiao()//小明今年30岁了

模板字符串

模板字符串:``

可以作为正常引号去使用

let str=`我是模板字符串`

可以在内容区出现换行,输出也会换行(正常引号不允许换行)

let str2=`
<ul>
	<li>沈腾</li>
	<li>艾伦</li>
</ul>`;//如果是单引号或双引号就需要使用+来拼接

变量拼接

let love='希儿'
let love_most=`${love}我最喜欢`
console.log(love_most)//希儿我最喜欢

对象的简写

let name='新东方'
let change=function(){
    console.log('新东方厨师')
}
const school={
    name,//相当于name:name 就是将上面的name属性变成school对象的属性
    change,//同理,change:change,将上面的change方法变成school的方法
    improve(){//完整写法:improve:function(){}
        console.log('我们可以提高你的技能')
    }
}

箭头函数

箭头函数是ES6非常重要的一个点,它的this是静态的,始终指向函数声明所在作用域下的this的值(无法改变),即函数本身所处的环境,默认指向父级对象

箭头函数适用于与this无关的回调:定时器,数组的方法回调

不适于与this有关的回调,事件回调,对象的方法

function getName(){
    console.log(this.name)
}
let getName2=()=>{
    console.log(this.name)
}
const name='新东方'
const school={name:'蓝翔'}
getName();//输出新东方
getName2();//输出新东方
getName.call(school);//输出蓝翔
getName2.call(school);//输出依旧是新东方,无法改变this指向

同时箭头函数无法作为构造函数实例化对象

const Person=(name,age)={
    this.name=name
    this.age=age
}
const jakc=new Person('jack',23)//错误,无法实例化

箭头函数无法使用argument变量

argument变量:函数调用传入的实参形成的伪数组

let fn2=()=>{
    console.log(argument)
}
fn2(1,2,3)//报错

箭头函数简写

省略小括号,当形参有且只有一个时

let add=n=>{
    return n+n
}
console.log(add(9))

省略大括号,但代码语句只有一条时,此时return必须省略

let pow=n=>n*n
console.log(pow(9))

箭头函数的作用域

 const cd={
     name:'新东方',
     getName2:function(){
         console.log(this);
     }
 }
cd.getName2();//输出为window

这里一般函数的this就是cd对象,箭头函数的this指向当前函数所处的作用域,按理来说也是cd对象,但是cd只是一个对象,没有作用域,所以箭头函数会继续向外寻找,最后就找到的是window

rest参数

arguments

用于获取函数实参

function date(){
    console.log(arguments)
}
date('柏芝','希子')//输出柏芝,希子

rest

同样用于获取函数参数,用于取代arguments

function fn(...args){//...是写法,args是名称
    console.log(args)
}
fn('阿娇','四惠')

如果有多个参数,rest参数必须放在最后

function fn(a,b,...c){
    console.log(a)//输出1
    console.log(b)//输出2
    console.log(c)//输出3 4 5 6
}
fn(1,2,3,4,5,6)

扩展运算符

样式:[...],扩展运算符可以将数组作为,分隔的参数序列

const tfboys=['易烊千玺','王俊凯','王源']
function chun(){
    console.log(arguments)
}
chun(...tfboys)//这样就将tfboys数组转为了三个参数序列传入

还可以进行数组合并

const k=['曾毅','玲花']
const f=['王太利','肖央']
const unite=[...k,...f]//这样数组就合并完成了
console.log(unite)//输出['曾毅','玲花','王太利','肖央']
//如果采用老方法就需要
const unite=k.concat(f)

还可以进行数组克隆

const a=['E','G','M']
const b=[...a]//数组克隆完毕
console.log(b)//输出['E','G','M']

还可以将伪数组变成真正的数组

const divs=document.querySelectorAll('div')
const divArr=[...div]//此时divArr就是一个真数组了

也可以将字符串变成数组

let str='hello word'
console.log([...str])//(10)['h','e','l','l','o','','w','o','r','d']

还可以拆分数组

const a=['E','G','M']
console.log(...a)//输出 E G M

Symbol

Symbol是一种新增的基本数据类型,表示独一无二的值

Symbol的值是唯一的,用来解决命名冲突的问题

Symbol值不能与其他数据进行运算

Symbol定义的对象属性不能使用for..in进行循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名

通过Symbol()创建Symbol类型

let s=Symbol()
console.log(s,typeof s)//输出Symbol() 'symbol'

可以在Symbol()的括号内写入一个标识,用来描述这个Symbol类型

let s1=Symbol('新东方')
let s2=Symbol('新东方')
console.log(s1===s2)//返回false,虽然两个Symbol描述相同,但不是同一个

使用Symbol.for()创建

let s1=Symbol.for('新东方')
let s2=Symbol.for('新东方')
console.log(s1===s2)//返回true
//通过Symbol.for创建的Symbol会在Symbol注册表寻找是否有相同描述的Symbol,如果有就返回这个,没有就新建

向对象中添加SSymbol类型方法

向对象中添加Symbol类型的属性或方法时,Symbol外边必须加上[]

方法一

let game={
    name:'俄罗斯方块',
    up:function(){}
}
let method={
    up:Symbol()
    down:Symbol()
}
game[method.up]=function(){//向game中添加method中的up属性,并为该属性添加一个方法
    console.log('我可以快速上升')
}
//适用场景:当我们需要向一个复杂对象添加属性方法时,我们并不清楚该对象内部有哪些属性/方法,那么我们在添加过程中就难免会出现重名的错误,那么我们就可以使用Symbol来添加从而避免这种情况
game[method.up]()//调用Symbol定义的方法

方法二

直接在对象中添加

let game={
    name:'狼人杀',
    [Symbol.for('say')]:function(){
        console.log('我可以发言')
    },
    [Symbol('boom')](){
        console.log('我可以自爆')
    }
}
let say=Symbol.for('say')
game[say]()//调用对象内部的Symbol方法

Symbol的一些内置属性

Symbol.hasInstance 当对其他对象使用Instance运算符时,判断是否为该对象的实例时,会调用这个方法

Symbol.isConcatSpreadable 对象的该属性对于是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开

Symbol.unscopables 该对象指定了使用with关键字时,哪些属性会被with环境排除

Symbol.match 当执行str.match(myObject)时,如果该属性存在,会调用他,返回该方法的返回值

Symbol.replace 当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值

Symbol.search 当该对象被str.seach(myObject)方法调用时,会返回该方法的返回值

Symbol.split 当该对象被str.split(myObject)方法调用时,会返回该方法的返回值

Symbol.iterator 对象进行foe...of循环时会调用Symbol.iterator方法,返回该对象的默认遍历器

Symbol.toPrimitive 该对象被转为原始类型的值时,会调用这个方法返回该对象对应的原始类型值

Symbol.toStringTag 在该对象上调用toString方法时,返回该方法的返回值

Symbol 创建衍生对象时,会调用该属性

迭代器

迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据经济只要部署Iterator接口,就可以完成遍历操作

ES6创建了一种新的遍历命令for...of循环,Iterator接口主要提供for...of消费,原生具备Iterator接口的数据(可以使用for...of)

Array,Arguments,Set,Map,String,TypedArray,NodeList这些数据类型都具有迭代器

const weth=['唐僧','孙悟空','猪八戒','沙悟净']
for(let v of weth){//使用迭代器的for..of遍历
    console.log(v)
}

对象不具有迭代器特性,但是如果要求使用迭代器去遍历,那么我们可以自己写一个迭代器

//自定义遍历数据
const banji={
    name:"一班",
    stus:[
        '小明',
        '小虎' 
    ],
    [Symbol.iterator](){//迭代器
        let index=0;
        let _this=this;
        return{
            next:function(){
                if(index<_this.stus.length){
                    const result={value:_this.stus[index],done:false}
                    index++;//下标自增
                    return result;
                }else{
                    return{value:undefined,done:true};
                }
            }
        }
    }
}
for(let v of banji){
    console.log(v);
}

生成器

生成器其实就是一个特色的函数,是用于解决异步编程,通过function *来定义

function * gen(){
    console.log(111)
    yield '一只没有耳朵'//这里yield是函数的分隔符,函数运行到这就会停止,()里面的是表达式
    console.log(222)
    yield '一只没有尾巴'
    console.log(333)
    yield '真奇怪'
}
//生成器函数调用需要使用next(),每一次调用就向下运行一步,相当于一个迭代器对象
//调用一次next()就执行一次,遇到yield就停止运行,返回yield的表达式,value是yield的描述,done表示当前函数是否执行完毕
let iter=gen()
console.log(iter.next())//输出{value: '一只没有耳朵', done: false}
console.log(iter.next())//{value: '一只没有尾巴', done: false}
console.log(iter.next())//{value: '真奇怪', done: false}
console.log(iter.next())//{value: undefined, done: true}
//既然是迭代器,那么也可以是for...of遍历
for(let v of gen()){
    console.log(v)//输出一只没有耳朵 一只没有尾巴 真奇怪
    //返回的都是yield表达式
}

生成器的参数传递

由于生成器的调用方式不同,我们可以向生成器中传入多个参数赋值

function * gen(arg){
    console.log(arg)
    let one=yield 111
    console.log(one)
    let two=yield 222
    console.log(two)
}
let iter=gen('AAA')
console.log(iter.next())
//next()方法可以传入参数
console.log(iter.next('BBB'))//第二次调用传入的实参作为第一个yield的返回结果,即one的值为AAA
console.log(iter.next('CCC'))//第三次调用传入的实参作为第一个yield的返回结果,即two的值为BBB
/*执行结果为
AAA
{value:111,done:false}
BBB
{value:222,done:false}
CCC
{value:undefined,done:true}
*/

生成器函数实例

js是单线程异步的,文件操作,网络操作,数据库操作都是异步编程

需求:1s后控制后台输出111,2s后输出222,3s后输出333

//纯用定时器也能实现,共耗时6s
//但是如果回调操作多了,就会形成回调地狱
setTimeout(()=>{
    console.log(111)
    setTimeout(()=>{
        console.log(222)
        setTimeout(()=>{
            console.log(333)
        },3000)
    },2000)
},1000)
//使用生成器
function one(){
    setTimeout(()=>{
        console.log(111)
        iter.next();//定时器是异步操作,此时let iter=gen()已经执行完毕,所以定时器内可以使用iter.next()
    },1000)
}
function two(){
    setTimeout(()=>{
        console.log(111)
        iter.next();
    },1000)
}
function three(){
    setTimeout(()=>{
        console.log(111)
        iter.next();
    },1000)
}
function * gen(){
    yield one()
    yield two()
    yield three()
}
let iter=gen()
iter.next()

需求:模拟获取 用户数据 订单数据 商品数据,先获取用户数据,在获取商品数据,最后获取订单数据

function getUsers(){
    setTimeout(()=>{
        let data='用户数据';
        iterator.next(data);//继续调用next,并传入数据,这样在生成器函数就可以获取数据
    },1000)
}
function getOrders(){
    setTimeout(()=>{
        let data='订单数据';
        iterator.next(data);
    },1000)
}
function getGoods(){
    setTimeout(()=>{
        let data='商品数据';
        iterator.next(data);
    },1000)
}
function * gen(){
    let users=yield getUsers()
    console.log(users)
    let orders=yield getOrders()
    console.log(orders)
    let goods=yield getUserGoods()
    console.log(goods)
}
let iterator=gen()
iterator.next()

Promise

Promise也是用于解决异步编程的,语法上是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果

//实例化Promise对象
const p=new Promise(function(resolve,reject){//resolve和reject这两个参数是Promise的两个方法,可以自己取
    setTimeout(function(){
        let data='数据库中的数据';
        resolve(data);
        let err='数据读取失败';
        reject(err);
    },1000)
});
//调用promise的then方法
p.then(function(value){//数据读取成功调用第一个回调
    console.log(value);
},function(reason){//数据没有读取成功就调用第二个调用
    console.error(reason);
})

promise封装读取文件

//引入fs模块
const fs=require('fs');
//调用方法读取文件
    fs.readFile('./resources/为学.md',(err,data)=>{
    //如果失败,抛出错误
    if(err) throw err;
    //如果没有出错,输出内容
    console.log(data.toString());
            });

//使用Promise封装
const p=new Promise(function(resolve,reject){
    fs.readFile('./resources/为学.md',(err,data)=>{
    //如果失败
    if(err) reject(err);
    //如果成功
    resolve(data);
    })
});

p.then(function(value){
    console.log(value.toString());
},function(reason){
    console.log("读取失败");
})

对于Promise,返回的是非Promise类型,那么状态为成功,返回值为对象的成功值,返回的是Promise类型,Promise的状态就是回调函数的状态,返回的是异常,回调函数的返回值就是抛出的异常

Promise的catch方法

用于设置promise对象失败的一个回调

const p=new Promise((res,rej)=>{
    rej('失败')
})
p.catch(function(res){
    console.log(res)
})

集合

集合也是用于存储数据,具有迭代器,可以使用for..of遍历

集合具有唯一性,会自动去掉内部重复项

//声明集合
let s=new Set()
let s1=new Set([1,2,3,4])
//集合元素个数
console.log(s1.size)//4
//向集合中添加(添加到最后位置)
s1.add('5')
//删除集合中元素
s1.delete(5)
//检测集合是否包含某元素
console.log(s1.has(2))
//清空集合
s1.clear()
//使用for of遍历
for(v of s1){
    console.log(v)
}

集合的使用

利用集合的唯一性,我们可以进行数组去重

let arr=[12,3,4,4,5,6,6]
let res=[...new Set(arr)]//使用扩展运算符将集合变成数组
console.log(res)

利用集合求交集

let arr1=[12,3,4,6,3,4]
let arr2=[12,4,7,3,4,5,6]
let result=[... new Set(arr1)].filter(item=>{
    let res=new Set(arr2)
    if(res.has(item)){
        return true
    }else{
        return false
    }
})
console.log(result)

利用集合求并集

let arr1=[12,3,4,6,3,4]
let arr2=[12,4,7,3,4,5]
let result=[... new Set([...arr1,...arr2])]
console.log(result)

利用集合求差集(即两个集合相比,只存在于一个集合的元素)

let arr1=[12,3,4,6,3,23,56]
let arr2=[12,4,7,3,4,5,6]
let result=[... new Set(arr1)].filter(item=>{
    let res=new Set(arr2)
    if(res.has(item)){
        return false
    }else{
        return true
    }
})
console.log(result)

MAP

Map类似于对象,也是键值对的集合,但是键的范围不限于字符串,各种类型的值(包括对象)都可以当作键

Map也实现了iterator接口,所有可以使用扩展运算符和for...of进行遍历。

Map的属性和方法

size 返回Map的元素个数

set 增加一个元素,返回当前Map

get 返回键名对象的键值

has 检测Map中是否有某个元素,返回boolean

clear 清空集合,返回undefiend

//声明MAP
let m=new Map()
m.set('name','新东方')
m.set('change',function(){
    console.log('我们可以改变你')
})
let key={
    school:'ATGUIGN',
}
m.set(key,['北京','上海','深圳'])//通过key对象向m中添加元素

console.log(m)
console.log(m.size)//3
//删除,通过键名进行删除
m.delete('name')
//读取,通过键名进行读取
m.get('change')
//读取,通过对象读取
m.get(key)
//遍历,遍历结果为三个数组
for(let v of m){
    console.log(v)
}
//清空
m.clear()

Class类

class类基于已有的对象系统,提供了更简洁和强大的方式来创建和组织对象

class Phone{
    //constructor是类的构造函数,一般用于初始化对象状态
    constructor(brand,price){//名称固定,实例化时自动执行
        this.brand=brand
        this.price=price
    }
    call(){//语法固定,不能使用call:function(){}语法
        console.log('我正在打电话')
    }
}
let onePlus=new Phone('华为',1999)
console.log(onePlus)
onePlue.call()

class的静态成员

使用static修饰的属性/方法称为静态属性/方法

静态成员只属于class类,不属于创建的实例对象,因此无法使用实例对象调用静态成员

class Phone{
    static name='手机'
    static change(){
        console.log('换手机')
    }
}
let phone=new Phone()
console.log(use.name)//无法调用,name不属于phone,属于Phone
console.log(Phone.name)//可以调用

class的继承

class类的继承需要使用extends关键字

class Phone{
    constructor(brand,price){
        this.brand=brand
        this.price=price
    }
    call(){
        console.log('我在打电话')
    }
}
//进行继承
class SmartPhone extends Phone{
    constructor(brand,price,color,size){
        super(brand,price)//继承父类的实例属性
        this.color=color
        this.size=size
    }
    photo(){
        console.log('我可以拍照')
    }
    game(){
        console.log('我可以打游戏')
    }
    call(){//通过重写父类的call方法,可以覆盖掉父类的该方法
        console.log('我在打视频电话')
    }
}

get与set

get将对象属性与函数进行绑定,属性被访问时,函数立即执行 set将对象属性与函数进行绑定,属性被赋值时,函数立即执行

class Phone{
    constructor(pric){
        this.pric=pric
    }
    get price(){
        console.log("价格已经传入");
        return this.pric;
    }
    set price(Val){
        this.pric=Val
        console.log("价格已经改变");
    }
}
let s=new Phone(1200);
console.log(s.price);//访问s的price方法,get price立即执行
console.log(s.price=1000);//赋值,set price立即执行,赋值作为set函数的返回值

数值扩展

js表示的最小精度为Number.EPSILON,无限趋向于2.22E-16,js认为两个数之间的差值小于EPSILON就是相等的

console.log(0.1+0.2===0.3)//这里输出为false,原因是因为底层的二进制导致的
//解决
function equal(a,b){
    if(Math.abs(a-b)<Number.EPSILON){//Mtah.abs()取绝对值
        return true
    }else{
        return false
    }
}
console.log(equal(0.1+0.2,0.3))//这里输出就为true

表示进制

let b = 0b1010;//二进制:0b+二进制
let o = 0o777;//八进制:0o+八进制
let d = 100;//十进制
let x = 0xfff;//十六进制:0x+十六进制
console.log(x)//输出会自动转为十进制

数值扩展方法

//Number.isFinite 检测一个数是否是有限数
console.log(Number.isFinite(100));//true
console.log(Number.isFinite(100 / 0));//false

//Number.isNaN 检测一个数值是否是NaN
console.log(Number.isNaN(123));//false

//Number.parseInt 截取字符串中数字为整型,无法截取小数点后面,遇到非数字停止截取
//Number.parseFloat 截取字符串中数字为浮点型,能截取小数点后面(只认第一个小数点),遇到非数字停止截取,e除外,会被当成数学符号
//两种方式没有截取到均返回NAN,均可以将其他进制转为十进制
console.log(Number.parseInt('11223love'));//11223
console.log(Number.parseFloat('2.12113s生器'));//2.12113

//Number.isInteger 判断一个数是否为整数
console.log(Number.isInteger(12));//true

//Math.trunc 将整数的小数部分抹掉
console.log(Math.trunc(3.89));//输出3

//Number.sign判断一个数是正数还是负数还是零
console.log(Math.sign(100));//正数返回1
console.log(Math.sign(-100));//负数返回-1
console.log(Math.sign(0));//零返回0

对象方法扩展

//1.Object.is 判断两个值是否完全相等,与===基本类型
console.log(Object.is(120,120));//返回true
//和全等号===的区别
console.log(Object.is(NaN,NaN));//返回true
console.log(NaN===NaN);//返回false
console.log(Object.is(+0,-0));//返回false
console.log(+0===-0);//返回true

//2.Object.assign 对象合并
const config1={
    host:'localhost',
    post:3306,
};
const config2={
    host:'http://atguigu.com',
    name:'atguigu.com',
}
console.log(Object.assign(config1,config2));
//如果有重名的,则config2覆盖consig1,即后面的覆盖前面的

//3.Object.setPrototypeOf 设置原型对象
//3.Object.getPrototypeOf 获取原型对象
const school={
    name:'新东方'
} 
const cities={
    xiaoqu:['北京','上海']
}
Object.setPrototypeOf(school,cities);//将cities对象设置为school的原型
console.log(school);
console.log(Object.getPrototypeOf(school));//获取school的原型

模块化

模块的暴露方式

//分别暴露
export let school='新东方'
export function b(){}
//统一暴露
let school='新东方'
function b(){}
export (school,b)
//默认暴露(暴露对象,但是没有对象名)
export default{
    school:’新东方
    b(){}
}

模块化导入方式

//通用方式 *表示导入全部 as取别名
import * as m1 from '../main.js'
//解构赋值形式,对于默认暴露,如果暴露的是对象,也需要使用别名,因为默认暴露没有对象名
import {school as m2} from '../main.js'
//简便形式(只能用于默认暴露的模块)
import m3 from '../main.js'

在实际中并不是所有浏览器都兼容所有的导入方式,所有我们在项目中经常使用babel进行转换,可以将es比较新的语法转为浏览器可以识别的语法

安装工具 babel-cli(命令行工具) babel-praset-env(预设包,转换代码) browserify(打包工具,项目中一般使用webpack)

1.终端输入npm init -yes(初始化)

2.安装(需要先安装Node.js),输入npm i babel-cli babel-preset-env browserify -D

3.转换 npx babel 源文件目录 -d 保存到的目录 --presets=babel-preset-env

npx babel ES\模块 -d dist\转换 --presets=babel-preset-env

4.打包 npx browserify 文件目录 -o 输出位置

npx browserify dist/转换/19-4模块化4.js -o dist/bundle4.js

ES7

includes

includes用来判断数组是否包含某个元素,返回布尔值

const zhu=['西游记','红楼梦','三国演义','水浒传']
console.log(zhu.includes('西游记'))//返回true

另一个indexOf返回的下标,没有返回-1

幂运算

使用**来实现幂运算

console.log(2**2)//输出4
//等价于
console.log(Math.pow(2,2))

ES8

async与await

async和await语法结合可以让异步代码和同步代码一样

async函数返回值是promise对象

promise对象的结果由async函数执行的返回值决定

async function fn(){
    return '新东方'//返回的不是promise对象,结果为成功
    return new Promise((resolve,reject)=>{
        resolve('成功')//返回为成功的promise
        reject('失败')//返回的为失败promise
    })
}

awiat函数必须写在async函数中,await返回的是promise的值,await的promise失败了,就会抛出异常,可以通过try...catch捕获

const p=new Promise((resolve,reject)=>{
    //reject('失败')
    resolve('成功')
})
async function main(){
    try{
        let result=await p
    }catch(e){
        console.log(e)
    }
}

对象方法扩展

const school={
    name:'新东方',
    cities:['北京','上海','深圳'],
}
//Object.keys 获取对象所有的键名(数组形式)
console.log(Object.keys(school))
//Object.values 获取对象所有的值(数组形式)
console.log(Object.values(school))
//Object.entries 返回一个将键名和键值组合起来的数组
console.log(Object.entries(school))
//Object.entries 可以用来创建MAP
const m=new Map(Object.entries(school))
console.log(m.get('name'))
//Object.getOwnPropertyDescriptors 返回对象属性的描述对象
console.log(Object.getOwnPropertyDescriptors(school))
//属性描述对象 writable,configurable,enumerable等,可以用于深层次的对象克隆

ES9

扩展运算符

function connect({host,...user}){//...user将剩下的对象存入
    console.log(host)
    console.log(user)
}
connect({
    host:'127.0.0.1',
    uaername:'root',
    password:123
})
//对对象的合并
const SkillOne={q:'金钟罩'}
const SkillTwo={w:'金钟罩'}
const mangsen={...SkillOne,...SkillTwo}//合并对象

正则表达式

边界符

//:匹配有其中内容的

^$:匹配有其中的内容开头且结尾的

let reg1=/123///匹配含有123的字符
console.log(reg1.test('ww123df'))//返回true
let reg2=/^abc$/ //匹配以abc开头的字符
console.log(reg2.test('abc'))//返回true
console.log(reg2.test('1abc1'))//返回false

字符

[] 匹配其中任意一个字符

let reg1=/[abc]///只要包含a或b或c就为true
console.log(reg1.test('wes'))//返回false
console.log(reg1.test('wbs'))//返回true

let reg2=/^[abc]$///匹配只以a或b或c开头结尾的,即只能是a或b或c
console.log(reg2.test('ab'))//返回false
console.log(reg2.test('c'))//返回true

let reg3=/^[a-z]$///匹配以英文字母表a-z开头结尾的,即只能输入a-z中的一个
console.log(reg3.test('f'))//返回true

let reg4=/^[^-_]$///[]内部的^表示取反,这里表示匹配非下划线
console.log(reg4.test('_'))//返回false
console.log(reg4.test('f'))//返回true

let reg5=/^[a-zA-Z0-9_]$///匹配大小写字母,数字0-9及下划线
console.log(reg5.test('A'))//返回true
console.log(reg5.test('9'))//返回true
console.log(reg5.test('$'))//返回false

量词符

* 表示可以出现任意次

+ 表示可以出现1次及以上

? 表示只能出现0次或1次

{2} 表示连续出现2次

let reg1=/a*/ //a可以出现任意次
console.log(reg1.tset('123'))//返回true
console.log(reg1.tset('aa'))//返回false

let reg2=/a+/ //a可以出现一次及以上
console.log(reg2.test('123'))
console.log(reg2.test('a'))

let reg3=/a?/ //a只能出现0次或1次
console.log(reg3.test('a'))
console.log(reg3.test('aaa'))

let reg4=/a{3}/ //a连续出现3次
console.log(reg4.tset('dsdaaaqw'))
let reg6=/a{3,}/ //a连续出现大于等于3次
let reg7=/a{3,5}/ //a连续出现次数范围在3-5之间,左闭右开
let reg8=/^(ab){2}/ //连续出现两次ab,且为开头结尾

let reg9=/^[a-zA-Z0-9_-/{5,10}$/ //限制输入只能为大小写字母,数字,下划线,中线,且长度为5-10

ES10

对象扩展方法

//Object.fromEntries用于创建一个对象,参数是一个二维数组或Map,即将二维数组或Map转为对象
//二维数组
const res=Object.fromEntries([
    ['name':'尚硅谷'],
    ['project':'Java,前端']
])
console.log(res)
//Map
const m=new Map()
m.set('name','ATGUIGU')
const result=Object.fromEntries(m)
console.log(result)

字符串扩展方法

//trim() 用于清除字符串两边的空白字符
//trimStart()(清除左边空白字符)和trimEnd()(清除右边空白字符)
let str=' iloveyou '
console.log(str.trim())
console.log(str.trimStart())
console.log(str.trimEnd())

数组扩展方法

//flat()将数组维度降低
const arr1=[1,2,3,4,[5,6,7]]
console.log(arr1.flat(1))//参数为数字,表示降几层,默认1,此时为[1,2,3,4,5,6,7]
//flatMap()对数组内容进行批量操作
const arr2=[1,2,3,4]
const res=arr2.flatMap(item=>[item*10])
console.log(res)//输出为[10,20,30,40]

提取Symbol描述

let s=Symbol('尚硅谷')
console.log(s.description)//输出为尚硅谷

ES11

类的私有属性

class Person{
    name;//公有属性
    #age;//私有属性
    constructor(name,age){
        this.name=name
        this.#age=age
    }
    intro(){
        console.log(this.name)
        console.log(this.#age)
    }
}
const girl=new Person('小哥',11)
console.log(girl.#age)//实例对象无法访问
console.log(Person.#age)//类也无法访问
girl.intro()//可以访问 输出 小哥 11

Promise.allSettled

Promise.allSettled接收一个Promise数组,返回一个Peomise对象,返回永远成功,值为某一个Promise的状态结果

const p1=new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve('商品数据-1');
    }, (1000))
});
const p2=new Promise((resolve,reject)=>{
    setTimeout(() => {
        //resolve('商品数据-2');
        reject('失败了');
    }, (1000));
});
const result=Promise.allSettled([p1,p2])
console.log(result)
//result的结果永远成功,如果传入的promise中有失败的,会在result中体现出来
//比如这里的值就是
//[[PromiseResult]]
//Array(2)
//0: {status: 'fulfilled', value: '商品数据-1'}
//1: {status: 'rejected', reason: '失败了'}

Promise.all

Promise.all接收一个Promise数组,数组内所有promise对象成功才返回成功,否则就失败

const result=Promise.all([p1,p2])

字符串扩展matchAll

//用来得到正则批量匹配的结果
let str=`
<ul
	<li>
		<a>肖申克的救赎</a>
		<p>上映日期:1994-09-10</p>
	</li>
	<li>
		<a>阿甘正传</a>
		<p>上映日期:1994-07-06</p>
	</li>
</ul>`;
//声明正则
const reg=/<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/sg
//调用正则
const result1=str.matchAll(reg);
console.log(result1);//可以发现结果有next方法,所有可以使用for...of进行遍历
for(let v of result1){
    console.log(v);
}
//使用扩展运算符展开
const arr=[...result1];
console.log(arr);

可选链

可选链操作符: ?. 前面为真才执行下一步操作

当我们应对对象类型层级比较深,而我们需要取进行判断时可以使用

function main(config){
    //这里就是在先判断config参数是否传入,传入就继续判断下一个,最终返回最后判断的结果,即前面为真才执行下一步
    const dbhost=config?.db?.host
    console.log(dbhost)
}
main({
    db:{host:'127.1.1.1'}
    cache:{}
})

动态导入模块

//实际开发中,我们一般会在一个js中导入许多模块,但是其中有一些我们可能不需要,就不能实现按需加载
//静态导入,不论你现在用不用,反正先导入
import * as m1 from './hello.js'
//动态导入,实现按需加载
btn.oncilck=function(){
    import('./hello.js').then(m1=>{//import返回是一个promise对象
        m1.hello()
    })
}

BigInt类型

BigInt:大整型 一般用于大数字计算

let num=521n //n就表示大整型
console.log(n,typeof(n))
//将其他类型变为大整型,不能使用浮点型
let m=123
console.log(BigInt(m))
//用于大数字计算
let max=Number.MAX_SAFE_INTEGER//这是js的最大安全数值
console.log(max+1)//无法继续增大
console.log(BigInt(max)+BigInt(3))//可以继续增大

绝对全局变量

globlThis:字面意思,无论执行文件,始终指向window

想操作全局变量时,就可以使用globThis直接操作从而忽略当前环境

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值