ES6-11笔记呀

ES6

1. let

let用来变量声明

特性:1.变量不能重复声明 2.块级作用域 3.不会变量提升

2. const

const用来声明常量

特性:1.一定要有初始值 2.值不能修改 3.块级作用域 4.对于数组或者对象的修改不算对常量的修改,不会报错

3. 变量的结构赋值

  • ES6允许按照一定模式从数组和对象中提取值,对变量进行复制

    • 数组的结构

      const XXX = ['xx','yy','zz']
      let [x,y,z] = XXX
    • 对象的结构

      const zhao = {
          name:'xxx',
          age:18,
          say: function(){}
      }
      let {say} = zhao

4. 模板字符串

新的字符串方式,用``声明

特性:1.内容中可以直接出现换行符 2.用${}直接进行变量拼接

5. 对象的简化写法

ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法

6. 箭头函数

ES6允许使用箭头来定义函数

特性:1.this是静态的,始终指向函数声明式所在的作用域下的this值 2.不能作为构造函数实例化对象 3.不能使用arguments变量

适用场景:与this无关的回调,定时器,数组的方法回调

不适用场景:与this有关的回调,事件回调,对象的方法

7. 函数参数的默认值

ES6允许参数赋初始值

// 如果不给c赋值,那么c就会等于初始值10
function add (a,b,c=10){}

8.rest参数

ES6引入rest参数,用于获取函数的实参,用来代替argument

function date(...args){
    console.log(args) // args是一个装剩余参数的数组,可以使用数组方法
}

9.扩展运算符

... 扩展运算符能将数组转换为逗号分隔的参数序列

const xxx = [1,2,3]
console.log(...xxx)    // 1,2,3
​
const xxx = {
    name: 'xxx',
    age: 18
}
console.log(...xxx)  // name:'xxx', age:18

与rest参数的区别:rest参数是形参,只能放在函数声明的参数里,扩展运算符可以展开数组,对象,伪数组

使用扩展运算符展开的元素是浅拷贝

10.Symbol

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值,他是JavaScript语言的第七种数据类型

特点:1. Symbol的值是唯一的,用来解决命名冲突的问题 2.Symbol值不能与其他数据进行运算 3.Symbol定义的对象属性不能使用for in 循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名

11.迭代器(Iterator)

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

  • ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费

    • for of保存的是键值,for in 保存的是键名

  • 原生具备iterator接口的数据(可用for of遍历)

    1. Array 2.Arguments 3.Set 4.Map 5.String 6.TypeArray 7.NodeList

  • 工作原理

    • 创建一个指针对象,指向当前数据结构的起始位置

    • 第一次调用对象的next方法,指针自动指向数据结构的第一个成员

    • 接下来不断调用next方法,调用一直往后移动,直到指向最后一个成员

    • 每调用next方法返回一个包含value和done属性的对象

  • 场景:自定义遍历数据

    let obj = {
        name:'xxx',
        stus:['xxx','yyy','zzz','aaa'],
        // 开启一个迭代器,来自定义遍历数据
        [Symbol.iterator](){
            let index = 0;
            return {
                next:() => {
                    if(index < this.stus.length){
                        const res = {value: this.stus[index], done:false}
                        index++
                        return result
                    }else {
                        return {value:undefined, done:true}
                    }
                }
            }
        }
    }

12.生成器

生成器是ES6提供的一种异步编程方式,语法行为与传统的函数完全不同

function * gen(){       // 生成器是一个特殊的函数
    console.log(111)
    yield 'xxxx'        // yield算是函数代码的分隔符,每掉一次next就会执行到一个yield的位置
    console.log(222)
    yield 'xxxx'
    console.log(333)
    yield 'xxxx'
    console.log(444)
}

解决异步编程

function getUsers() {
    setTimeout(() => {
        let data = '用户数据'
        iterator.next(data)
    }, 1000}
}
function getGoods() {
    setTimeout(() => {
        let data = '商品数据'
        iterator.next(data)
    }, 1000}
}
function getOrders() {
    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 getGoods();
    console.log(goods)
}
let iterator = gen()
iterator.next()

13.Promise

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

callback hell:

// 通过回调的方式来保证异步函数的执行顺序,但会陷入回调地狱
fs.readFile('/data/a.txt', 'utf8', (err, data) => {
    if(err) {
        throw err 
    }
    console.log(data)
    fs.readFile('/data/b.txt', 'utf8', (err, data)=> {
        if(err) {
            throw err
        }
        console.log(data)
        fs.readFile('/data/c.txt', 'utf8', (err, data)=> {
            if(err) {
                throw err
            }
            console.log(data)
        })
    })
})

为了解决以上编码方式带来的问题(回调地狱嵌套),所以在ES6中新增了一个API:promise

  • Promise的英文就是保证,承诺的意思

  • Promise容器中存放了一个任务

  • 有三种状态,Pending, Resolved, Rejected,成功了状态就从Pending -> Resolved,失败了就从 Pending -> Rejected

创建一个Promise容器

  • promise容器一旦创建,就开始执行里面的代码

let p1 = new Promise((resolve, reject) => {
    // 这是一个异步任务
    fs.readFile('/data/a.txt', 'utf8', (err, data) => {
        if(err) {
            // 失败了,承诺容器中的任务失败了
            // 把容器的Pending状态改成Rejected
            // 这里调用的resolve调用的第二个function
            reject(err)
        }else {
            // 承诺容器的任务成功了
            // 把容器的Pending状态改成Resolve
            // 这里调用的resolve调用的第一个function
            resolve(data)
        }
    })
})
​
// 当p1成功了,然后可以调用then做指定的动作
// then方法接收的function就是容器中的resolve
p1.then(data => {
    console.log(data)
},err => {
    console.log(err)
})

解决异步编程嵌套问题

let p1 = new Promise((resolve, reject) => {
    fs.readFile('/data/a.txt', 'utf8', (err, data) => {
        if(err) {
            reject(err)
        }else {
            resolve(data)
        }
    })
})
​
let p2 = new Promise((resolve, reject) => {
    fs.readFile('/data/b.txt', 'utf8', (err, data) => {
        if(err) {
            reject(err)
        }else {
            resolve(data)
        }
    })
})
​
p1.then(data => {
    console.log(data)
    // 当前函数中 return 的结果就可以在后面的then中function 接收到(return 什么接收到就是什么,没有就会收到undefined)
    // 当return 一个Promise对象的时候,后面的then中的方法的第一个参数会作为p2 的resolve方法来调用
    return p2
},err => {
    console.log(err)
})
  .then(data => {
    console.log(data)
},err => {
    console.log(err)
})

Promise的catch方法

catch方法算是then方法的一个语法糖,只能指定失败的回调

14.Set

ES6 提供了新的数据结构Set(集合),它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用扩展运算符和for of进行遍历

声明Set:let s = new Set([]) 可传入一个可迭代对象

let s = new Set(['xx','yy','zz','aa','xx'])  // {'xx','yy','zz','aa'},Set会自动去重

api:

  • size 元素个数,是一个属性

  • add() 添加新的元素

  • delete() 删除一个元素

  • clear() 清空集合

15. Map

ES6 提供了Map数据结构,他类似于对象,也是键值对的集合,但是键的范围不限于字符串,各种类型的值(包括对象)都可以当作键,Map也实现了iterator接口,可以使用扩展运算符和for of进行遍历

声明:let m = new Map()

api:

  • size 元素个数,是一个属性

  • set(key, value) 添加一个键值对,key可以是任意数据类型

  • delete(map.get(key)) 删除一个元素

  • clear() 清空Map

16.class类

ES6提供了更接近传统语言的写法,引入Class类这个概念,作为对象的模板,通过Class关键字,可以定义类,ES6的class可以看作一个语法糖,他的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰,更像面向对象的写法而已

使用class关键字来声明类 class Phone{}

class Phone {
    custructor(brand, price) {  // 构造器
        this.brand = brand
        this.price = price
    }
    call (){}   // 定义方法,只能使用es6的语法
}

使用static关键字来声明类里面的静态成员,静态成员只有类内部能够访问,实例对象无法访问静态成员

class Phone {
    static name = '手机'
    static change() {} 
}

es6类的继承

class Son extends Parent {
    custructor(brand, price, color, size){
        super(bradn, price)     // 相当有调用了父类的构造函数 ==> Phone.call(this, brand, price)
        this.color = color
        this.size = size
    } 
    photo() {}
    playGanme() {}
}

继承之后 父类的方法会在子类的原型链上

子类可以对父类方法的重写,重写同名方法后,实例对象调用方法会是子类的方法

class种getter和setter的设置

class Phone{
    get price(){    // 当price属性被读取时会自动调用getter
        console.log('price属性被读取了')
    }
    set price(newVal){  // 当price属性被修改时会自动调用setter
        console.log('price属性被修改了,修改成了' + newVal)
    }
}

17. 数值扩展

  • Number.EPSILON 是JS表示的最小精度, 接近2.22E-16,可以实现小数的运算精度问题

    // 在JS中,小数运算 0.1 + 0.2 !== 0.3
    // 我们可以定义一个方法,如果两个数差值 < number.EPSILON的话,我们就认为他是相等的
    function equal(a, b) {
        if(Math.abs(a-b) < Number.EPSILON) {
            return true
        } else {
            return false
        }
    }
  • 进制

    // 二进制0b开头,八进制0o开头,十六进制0x开头
    let b = 0b1010 // 10
    let o = 0o777  // 511
    let x = 0xff   // 255
  • Number.isFinite 用于检测一个数是不是有限数

  • Number.isNaN 用于检测一个数值是否为NaN

  • Number.parseInt Number.parseFloat 字符串转整数

  • Number.isInteger 用于检测一个数值是不是整数

  • Number.trunc 用于把数字的小数部分抹掉

  • Number.sign 用于判断一个数到底是正数 负数 还是0 正数返回1 0返回0 负数返回-1

18.对象方法扩展

  • Object.is 判断两个值是否相等 该方法判断NaN和NaN,返回true

  • Object.assign 对象的合并

    const obj = {
        host: 'localhost',
        port: 3306,
        name: 'root',
        pass: 'root'
    }
    const obj2 = {
        host: 'http://atguigu.com',
        port: 33060,
        name:'atguigu.com',
        pass:'iloveyou'
    }
    console.log(Object.assign(obj, obj2))   // 如果属性名不同则合并,要是一样就后者覆盖前者,合并的对象为浅拷贝
  • Object.setPrototypeOf 设置原型对象

  • Object.getPrototypeOf 获取原型对象

    const school = {
        name: '尚硅谷'
    }
    const cities = {
        city: ['北京', '上海', '深圳']
    }
    Object.setPrototypeOf(school, cities) // 给school设置原型对象
    console.log(school)

19. ES6模块化

  • 指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来

  • 好处:1. 防止命名冲突 2. 代码复用 3. 高维护性

  • ES6之前的模块化:

    • CommonJS => Node.js

    • AMD => requireJS

    • CMD => sea.JS

  • ES6模块化语法:由两个命令构成:export 和 import

    • export 用于规定模块的对外接口

    • import 用于输入其他模块提供的功能

  • 模块中3种暴露方式:1. export const xxx = 'xxx' 分别暴露 2.export {} 统一暴露 3. export default {} 默认暴露

  • 模块中3种引入方法:1. import * as m1 from 'xxx' 通用引入 2.import {xx, yy} from 'xxx' 结构赋值引入,针对分别暴露和统一暴露 3.import m3 from 'xxx' 简便引入,针对默认暴露

20.Proxy和Reflect

Proxy即代理,可以代理数据(对象/数组/方法)提供13种方法拦截数据(Object.defineProperty只有两种方法)

Reflect即反射,提供了13种方法反射数据,和Proxy一一对应

Proxy构造函数可传入两个参数

  • target:目标对象

  • handler:具体操作

new Proxy(target, {
    // 针对数据的拦截
    get set has deleteProperty
    // 遍历的拦截
    ownKeys
    // 属性描述器的拦截
    getOwnPropertyDescriptor defineOwnProperty
    // 是否可以扩展
    isExtensible preventExtensible
})

ES7

1.数组includes方法

如果包含返回true,不包含就返回false

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

2.幂运算**

ES7 提供了幂运算符

2 ** 10 = 1024相当于Math.pow(2, 10)

ES8

1.async 和 await

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

async表达式

在函数声明前面加上async修饰符来定义一个async函数,这个函数返回一个Promise对象,如果函数return一个字符串,则async返回一个成功的promise,如果throw Error,则async返回的就是一个失败的promise,如果return一个Promise对象,那么async返回的就是这个Promise状态的值

await表达式

await要放在async里面,await右侧的表达式一般为promise对象,await返回的是promise成功的值,await的promise失败了就会抛出异常,需要通过try..catch捕获处理

function sendAJAX(url) {
    return new Promise((resolve, reject) => {
        const x = new XMLHttpRequest();
        x.open('GET', url)
        x.send()
        x.onreadystatechange = function() {
            if(x.readyState === 4){
                if(x.status >= 200 && x.status < 300) {
                    resolve(x.response)
                } else {
                    reject(x.status)
                }
            }
        }
    })
}
​
async function main(){
    // 实现异步编程,类似于同步编程
    let result = await sendAJAX('url')
    let result = await sendAJAX('url2')
}

2. 对象方法扩展

  • Object.values() 返回一个给定对象的所有可枚举值的数组

  • Object.entries() 返回一个给定对象自身可遍历属性[key, value]数组

  • Object.getOwnPropertyDescriptors() 返回指定对象所有自身属性的描述对象(writable,configurable,enumerable)

ES9

1. 对象的剩余参数和扩展运算符

function connent({host, port, ...user}){  // 剩余参数会存在user对象种
    xxxx
}
​
const mangseng = {...tianyinbo, ...jinzhongzhao, ...tianleipo, ...menglongbaiwei} // 里面四个对象会被展开到mangseng中去

2.正则扩展-命名捕获分组

// 正则命名捕获
let str = '<a herf="www.baidu.com">百度</a>'
const reg = /<a href="(.*)">(.*)<\/a>/   // 提取url和标签文本
const result = reg.exec(str)   // 返回一个数组,0:匹配的字符串 1:捕获的第一位  2:捕获的第二位
​
// 正则命名捕获分组
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/   // 使用?<>分组,值会存在group对象里面

3.正则扩展-反向断言

// 正则正向断言
let str = 'JS5211314你知道吗555啦啦啦'
const reg = /\d+(?=啦)/    // 匹配后面跟着啦字的数字字符串
const result = reg.exec(str)
​
// 正则反向断言
const reg = /\(?<=啦)d+/

4.dotAll模式

const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs    // 正则后面加一个s,表示dotAll模式,这是.就能匹配任意字符

ES10

1.对象扩展方法

  • Object.fromEntries() 将二位数组转换成为对象,是Object.entries的逆运算

2.字符串扩展方法

  • trimStart 清除字符串左侧空白

  • trimEnd 清除字符串右侧空白

3.数组的扩展方法

  • flat 将多维数组转化为低维的数组

  • flatMap 将多维数组转化为低维的数组在进行map操作

ES11

1.私有属性

class类里面定义私有属性,不能被实例访问,只能在类的内部用

class Person {
    // 私有属性
    #age
    #weight
    custructor(name, age, weight) {
        this.name = name
        this.#age = age
        this.#weight = weight
    }
}

2.Promise.allSettled

接收一个promise数组参数

返回的结果始终是成功的,值是数组里面所有promise执行的结果

与Promise.all的区别

  • Promise.allSettled始终返回成功,all要数组里大的promise的执行结果全部成功,才会返回成功,否则返回失败

  • Promise.allSettled返回数组里面promise的执行结果,all要数组里的promise全部执行成功,才会返回全部的执行结果,否则返回失败的执行结果

3.String.prototype.matchAll

const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs
const result = str.matchAll(reg)  // 匹配全部符合reg的字符串,并存入一个数组里

4.可选链操作符

免去我们去层层判断有没有传入

function main(config){
    // 之前的写法
    const dbHost = config && config.db && config.db.host
    // 可选链写法
    const dbHost = config?.db?.host
}

5.动态import

ES11提供了import函数来进行动态引入,返回值是一个promise对象,成功就返回一个module对象(导出来的module)

不在页面加载时import,等要调用的时候在import,不影响加载的效率

6.Bigint

大整形 声明:let n = 521n / let n = BigInt(123)

可以做大数值运算

let max = Number.Max_SAFE_INTEGER;

console.log(BigInt(max) + BigInt(2)) // 大整形只能和大整形运算,不能和原始类型运算

7.绝对全局对象globalThis

ES11提供了绝对全局对象globalThis始终指向全局,浏览器指向window,Node指向global

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值