我是靠谱客的博主 忐忑猎豹,最近开发中收集的这篇文章主要介绍ES6学习笔记(包括ES6-ES11常用特性),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

ES6

    • 1.let变量声明及声明特性
      • 1.1 变量声明
      • 1.2 不能重复声明
      • 1.3 块级作用域
      • 1.4 不存在变量提升*
      • 1.5 不影响作用域链
    • 2. const声明常量及其特性
      • 2.1 声明方法
    • 3. 变量的解构赋值
      • 3.1 数组的解构
      • 3.2 对象的解构
    • 4. 模板字符串
      • 数据类型:String
      • 声明:
      • 内容中可以出现换行符
      • 变量拼接
    • 5. 对象的简化写法
    • 6. 箭头函数及其声明特点
      • 6.1 声明方法
      • 6.2 特性
        • 6.2.1 静态this
        • 6.2.2 不能作为构造函数实例化对象
        • 6.2.3 不能使用arguments对象
        • 6.2.4 箭头函数的简写
          • 6.2.4.1 省略小括号
          • 6.2.4.2 省略花括号
          • 6.2.4.3 案例
        • 6.2.5 箭头函数的应用场景
    • 7. 函数参数的默认值
    • 8. rest参数
    • 9. 扩展运算符
      • 9.1 扩展运算符的应用
        • 9.1.1 数组的合并
        • 9.1.2 数组的拷贝
        • 9.1.3 将维数组转换为真正的数组
    • 10. Symbol数据类型
      • 10.1 Symbol的创建
      • 10.2 向对象中添加Symbol类型的属性
      • 10.3 Symbol的内置属性
        • 10.3.1 Symbol.hasInstance 对象类型检测
        • 10.3.2 Symbol.isConcatSpreadable
    • 11. 迭代器
    • 12. 生成器函数
      • 12.1 生成器函数的声明与调用
      • 12.2 next方法
      • 12.3 yield理解
    • 13. Promise
      • 13.1 Promise的基本使用
      • 13.2 Promise读取文件
      • 13.3 Promise封装AJAX请求
      • 13.4 then方法
        • 13.4.1 返回的Promise对象的状态
        • 13.4.2 链式调用
      • 13.5 catch方法
    • 14. Set
    • 15. Map
    • 16. class类
      • 16.1 class声明类
      • 16.2 constractor定义构造函数初始化
      • 16.3 extends继承父类,super调用父级构造方法
      • 16.4 父类方法可以重写
      • 16.5 getter和setter
    • 17. 数值扩展
      • 17.1 Number.EPSILON是JS最小精度
      • 17.2 进制运算
      • 17.3 其他
    • 18. ES5-ES6对象方法拓展
      • 18.1 Object.is判断两个值是否完全相等,如果是对象的话,必须是同一个引用。
      • 18.2 Object.assign 对象的合并
      • 18.3 Object.setPrototypeOf设置原型对象
    • 19. 模块化
      • 19.1 模块暴露语法汇总
        • 19.1.1 分别暴露
        • 19.1.2 统一暴露
        • 19.1.3 默认暴露(VUE常用)
      • 19.2 模块引入语法汇总
        • 19.2.1 通用的导入方式
        • 19.2.2 解构赋值的形式
        • 19.3.3 简便形式(only默认暴露)
      • 19.3 入口文件方式
    • 20. ES7新特性
      • 20.1 **幂运算
    • 21. ES8新特性
      • 21.1 async
      • 21.2 await
      • 21.3 async await 读取文件
      • 21.4 async,await封装ajax请求
    • 22. ES8对象方法拓展
      • 22.1 Object.values()和Object.entries()
      • 22.2 Object.getOwnPropertyDescriptors获取对象属性的描述对象
    • 23. ES9
      • 23.1 rest参数
      • 23.2 扩展运算符
    • 24. ES10新特性
      • 24.1 Object.fromEntries()
      • 24.2 字符串方法 trimStart()和trimEnd()
      • 24.3 数组方法 flat()和flatMap()
      • 24.4. 私有属性
      • 24.5 Promise.Allsettled()方法
      • 24.6 ==可选链操作符==
      • 24.7 动态引入
      • 24.8 BigInt类型

1.let变量声明及声明特性

1.1 变量声明

    let a;
    let b, c, d;
    let e = 100;
    let f = 1, g = 2, h = 3;

1.2 不能重复声明

     let star='a'
     let star='b'

报错,但是var可以

1.3 块级作用域

全局,函数,eval

{
let girl = '丁心宜'
}
console.log(girl)

let 打印不出,var 可以

1.4 不存在变量提升*

console.log(song)
let song = '小燕子穿花衣'

会报错
但是用var相当于

var song;
console.log(song)
let song='小燕子穿花衣'
//undefined

不报错

1.5 不影响作用域链

虽然是块级作用域,但不影响作用域链

作用域链(Scoped chain):由子级作用域返回父级作用域中寻找变量,就叫做作用域链。

    {
      let score = '120'
      function fn1() {
        let school = '山东大学'
        function fn() {
          console.log(school);
          console.log(score)
        }
        fn();
      }
      fn1()
    }

两个变量都能打印出来。这里为了说明问题,用了两层,其实多少层都能寻找到变量。

2. const声明常量及其特性

文章目录

    • 1.let变量声明及声明特性
      • 1.1 变量声明
      • 1.2 不能重复声明
      • 1.3 块级作用域
      • 1.4 不存在变量提升*
      • 1.5 不影响作用域链
    • 2. const声明常量及其特性
      • 2.1 声明方法
    • 3. 变量的解构赋值
      • 3.1 数组的解构
      • 3.2 对象的解构
    • 4. 模板字符串
      • 数据类型:String
      • 声明:
      • 内容中可以出现换行符
      • 变量拼接
    • 5. 对象的简化写法
    • 6. 箭头函数及其声明特点
      • 6.1 声明方法
      • 6.2 特性
        • 6.2.1 静态this
        • 6.2.2 不能作为构造函数实例化对象
        • 6.2.3 不能使用arguments对象
        • 6.2.4 箭头函数的简写
          • 6.2.4.1 省略小括号
          • 6.2.4.2 省略花括号
          • 6.2.4.3 案例
        • 6.2.5 箭头函数的应用场景
    • 7. 函数参数的默认值
    • 8. rest参数
    • 9. 扩展运算符
      • 9.1 扩展运算符的应用
        • 9.1.1 数组的合并
        • 9.1.2 数组的拷贝
        • 9.1.3 将维数组转换为真正的数组
    • 10. Symbol数据类型
      • 10.1 Symbol的创建
      • 10.2 向对象中添加Symbol类型的属性
      • 10.3 Symbol的内置属性
        • 10.3.1 Symbol.hasInstance 对象类型检测
        • 10.3.2 Symbol.isConcatSpreadable
    • 11. 迭代器
    • 12. 生成器函数
      • 12.1 生成器函数的声明与调用
      • 12.2 next方法
      • 12.3 yield理解
    • 13. Promise
      • 13.1 Promise的基本使用
      • 13.2 Promise读取文件
      • 13.3 Promise封装AJAX请求
      • 13.4 then方法
        • 13.4.1 返回的Promise对象的状态
        • 13.4.2 链式调用
      • 13.5 catch方法
    • 14. Set
    • 15. Map
    • 16. class类
      • 16.1 class声明类
      • 16.2 constractor定义构造函数初始化
      • 16.3 extends继承父类,super调用父级构造方法
      • 16.4 父类方法可以重写
      • 16.5 getter和setter
    • 17. 数值扩展
      • 17.1 Number.EPSILON是JS最小精度
      • 17.2 进制运算
      • 17.3 其他
    • 18. ES5-ES6对象方法拓展
      • 18.1 Object.is判断两个值是否完全相等,如果是对象的话,必须是同一个引用。
      • 18.2 Object.assign 对象的合并
      • 18.3 Object.setPrototypeOf设置原型对象
    • 19. 模块化
      • 19.1 模块暴露语法汇总
        • 19.1.1 分别暴露
        • 19.1.2 统一暴露
        • 19.1.3 默认暴露(VUE常用)
      • 19.2 模块引入语法汇总
        • 19.2.1 通用的导入方式
        • 19.2.2 解构赋值的形式
        • 19.3.3 简便形式(only默认暴露)
      • 19.3 入口文件方式
    • 20. ES7新特性
      • 20.1 **幂运算
    • 21. ES8新特性
      • 21.1 async
      • 21.2 await
      • 21.3 async await 读取文件
      • 21.4 async,await封装ajax请求
    • 22. ES8对象方法拓展
      • 22.1 Object.values()和Object.entries()
      • 22.2 Object.getOwnPropertyDescriptors获取对象属性的描述对象
    • 23. ES9
      • 23.1 rest参数
      • 23.2 扩展运算符
    • 24. ES10新特性
      • 24.1 Object.fromEntries()
      • 24.2 字符串方法 trimStart()和trimEnd()
      • 24.3 数组方法 flat()和flatMap()
      • 24.4. 私有属性
      • 24.5 Promise.Allsettled()方法
      • 24.6 ==可选链操作符==
      • 24.7 动态引入
      • 24.8 BigInt类型

2.1 声明方法

const 变量名 =

注意事项:

  1. 声明的时候要赋初值*
  2. 一般常量名全部大写(潜规则)
  3. 常量不能重新赋值
  4. 块级作用域*
{
    const PLATER='DXY'
}
console.log(PLAYER)
//ERROR:not defined
  1. 对于数组和对象的元素修改,因为地址没有发生改变,因此不算做对常量的修改,不会报错*
const ARR = [1,2,3,4]
ARR.push(5)
// 不报错

3. 变量的解构赋值

3.1 数组的解构

const F4=['迪丽热巴','古力娜扎','杨幂','刘诗诗'];
let [di,gu,yang,liu] = F4;
console.log(di)
//迪丽热巴

3.2 对象的解构

const zhao = {
    name: '赵本山',
    age: '不详',
    xiaopin: function(){
        console.log('我可以演小品')
    }
}
let {name,age,xiaopin} = zhao
xiaopin()
// 或者
let {xiaopin} = zhao
xiaopin()

4. 模板字符串

数据类型:String

声明:

let str=`模板字符串`

内容中可以出现换行符

变量拼接

let lovest = 'AngelaBaby';
let out = `${lovest} is the BEST actress in my heart!`

5. 对象的简化写法

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

    let name = 'dxy'
    let age = 21
    let speak = function () {
      console.log('我爱说废话');
    }
    const person = {
      name, // 即:name:name
      age, // 即:age:age
      speak // 即:speak.speak
      improve(){
          console.log(111)
      }
      /*
      等同于:
      improve:functon(){
         console.log(111)
      }
      **/
    }
    person.speak()

6. 箭头函数及其声明特点

文章目录

    • 1.let变量声明及声明特性
      • 1.1 变量声明
      • 1.2 不能重复声明
      • 1.3 块级作用域
      • 1.4 不存在变量提升*
      • 1.5 不影响作用域链
    • 2. const声明常量及其特性
      • 2.1 声明方法
    • 3. 变量的解构赋值
      • 3.1 数组的解构
      • 3.2 对象的解构
    • 4. 模板字符串
      • 数据类型:String
      • 声明:
      • 内容中可以出现换行符
      • 变量拼接
    • 5. 对象的简化写法
    • 6. 箭头函数及其声明特点
      • 6.1 声明方法
      • 6.2 特性
        • 6.2.1 静态this
        • 6.2.2 不能作为构造函数实例化对象
        • 6.2.3 不能使用arguments对象
        • 6.2.4 箭头函数的简写
          • 6.2.4.1 省略小括号
          • 6.2.4.2 省略花括号
          • 6.2.4.3 案例
        • 6.2.5 箭头函数的应用场景
    • 7. 函数参数的默认值
    • 8. rest参数
    • 9. 扩展运算符
      • 9.1 扩展运算符的应用
        • 9.1.1 数组的合并
        • 9.1.2 数组的拷贝
        • 9.1.3 将维数组转换为真正的数组
    • 10. Symbol数据类型
      • 10.1 Symbol的创建
      • 10.2 向对象中添加Symbol类型的属性
      • 10.3 Symbol的内置属性
        • 10.3.1 Symbol.hasInstance 对象类型检测
        • 10.3.2 Symbol.isConcatSpreadable
    • 11. 迭代器
    • 12. 生成器函数
      • 12.1 生成器函数的声明与调用
      • 12.2 next方法
      • 12.3 yield理解
    • 13. Promise
      • 13.1 Promise的基本使用
      • 13.2 Promise读取文件
      • 13.3 Promise封装AJAX请求
      • 13.4 then方法
        • 13.4.1 返回的Promise对象的状态
        • 13.4.2 链式调用
      • 13.5 catch方法
    • 14. Set
    • 15. Map
    • 16. class类
      • 16.1 class声明类
      • 16.2 constractor定义构造函数初始化
      • 16.3 extends继承父类,super调用父级构造方法
      • 16.4 父类方法可以重写
      • 16.5 getter和setter
    • 17. 数值扩展
      • 17.1 Number.EPSILON是JS最小精度
      • 17.2 进制运算
      • 17.3 其他
    • 18. ES5-ES6对象方法拓展
      • 18.1 Object.is判断两个值是否完全相等,如果是对象的话,必须是同一个引用。
      • 18.2 Object.assign 对象的合并
      • 18.3 Object.setPrototypeOf设置原型对象
    • 19. 模块化
      • 19.1 模块暴露语法汇总
        • 19.1.1 分别暴露
        • 19.1.2 统一暴露
        • 19.1.3 默认暴露(VUE常用)
      • 19.2 模块引入语法汇总
        • 19.2.1 通用的导入方式
        • 19.2.2 解构赋值的形式
        • 19.3.3 简便形式(only默认暴露)
      • 19.3 入口文件方式
    • 20. ES7新特性
      • 20.1 **幂运算
    • 21. ES8新特性
      • 21.1 async
      • 21.2 await
      • 21.3 async await 读取文件
      • 21.4 async,await封装ajax请求
    • 22. ES8对象方法拓展
      • 22.1 Object.values()和Object.entries()
      • 22.2 Object.getOwnPropertyDescriptors获取对象属性的描述对象
    • 23. ES9
      • 23.1 rest参数
      • 23.2 扩展运算符
    • 24. ES10新特性
      • 24.1 Object.fromEntries()
      • 24.2 字符串方法 trimStart()和trimEnd()
      • 24.3 数组方法 flat()和flatMap()
      • 24.4. 私有属性
      • 24.5 Promise.Allsettled()方法
      • 24.6 ==可选链操作符==
      • 24.7 动态引入
      • 24.8 BigInt类型

6.1 声明方法

声明一个函数:

// 一般
let fn = function(a,b){
   //代码体 
}
// 箭头函数
let fn = (a,b) => {
    //代码体
}

6.2 特性

6.2.1 静态this

箭头函数的this是静态的,时钟指向函数声明时所在作用域下this的值。

  function getName() {
      console.log(this.name)
    }
    let getName2 = () => {
      console.log(this.name)
    }
    window.name = '窗体对象name'
    const obj = {
      name: "一个对象的名字"
    }
    // getName(); 
    // getName2();
    // 都会返回window.name
     
    // call方法调用
    getName.call(obj)
    // this被动态的改为对象
    getName2.call(obj)
    // this还是原来的窗体

另外一个例子:
需求,点击方块立刻变成粉色。
普通写法,需要将this存起来,因为function的this指向会发生改变

    let ad = document.getElementById('ad')
    ad.addEventListener("click", function () {
      let _this = this
      let changeColor = function () {
        _this.style.background = 'pink'
      }
      changeColor()
    })

箭头函数写法,不用存this,因为箭头函数的this是静态的,它的this就指向function的this,即名为ad的变量。

    let ad = document.getElementById('ad')
       ad.addEventListener("click", function () {
       changeColor = () => {
         this.style.background = 'pink'
       }
      changeColor()
    })

6.2.2 不能作为构造函数实例化对象

个人理解是,既然this在声明时已经指向函数所在作用域下this的值,那么this就不能再重新赋值,作为一个新的对象了。(不能把窗体作为一个刚new的Person对象)
错误示例:

    let Person = (name, age) => {
      this.name = name
      this.age = age
    }
    let me = new Person('xiao', 30)
    console.log(me)
    //Uncaught TypeError: Person is not a constructor

6.2.3 不能使用arguments对象

arguments对象是在函数调用时存储形参的对象

function func1(a, b, c) {
  console.log(arguments[0]);
  // expected output: 1

  console.log(arguments[1]);
  // expected output: 2

  console.log(arguments[2]);
  // expected output: 3
}

func1(1, 2, 3);

但是箭头函数没有这个对象

    let fn = () => {
      console.log(arguments);
    }
    fn()
    //Uncaught ReferenceError: arguments is not defined

6.2.4 箭头函数的简写

6.2.4.1 省略小括号

当形参有且只有一个时。

let add = n =>{
   return n+n
}
console.log(add(9))
//18
6.2.4.2 省略花括号

当代码体只有1条语句时,此时return也必须省略,而且语句的执行结果就是函数的返回值。

let pow = n => n * n
console.log(pow(9))
6.2.4.3 案例
const arr=[1,6,9,10,100,25]
const result=arr.filter(function(item){
    if(item%2===0){return true}
    else{return false}
})

箭头函数简写:

const result = arr.filter(item=>item%2===0)

结果都是[6,10,100],都是对的。

6.2.5 箭头函数的应用场景

  • 适合于this无关的回调,定时器,数组的方法回调
  • 不适合与this有关的回调,事件回调,对象的方法
    比如:
{
    name:'Sabina',
    getName:function(){
        return this.name;
        //可以拿到这个对象name
    }
    getName1:()=>{
        return this.name
        //这个时候的this指向的是外层作用域的this值
    }
}

7. 函数参数的默认值

如果不赋值,即为undefined

或者,与解构赋值结合:

function connect({host='127.0.0.1',username,pswd,port}){
    
}
connect({
    host:'baidu.com',
    username:'root',
    pswd:'123456',
    port:3306
})

8. rest参数

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

  • ES5获取实参的方式:
function date(){
    console.log(arguments)
}
date('丁小宜','丁心宜','dxy')

打印出来的arguments是一个对象

  • ES6通过rest参数获取实参:
function date(...args){
    console.log(args)
}
date('丁小宜','丁心宜','dxy')

打印出来的是一个数组。注意,如果方法有多个参数,要把arguments放在最后。

function fn(a,b,...args){
    console.log(a)//1
    console.log(b)//2
    console.log(args)//[3,4,5,6]
}
fn(1,2,3,4,5,6)

9. 扩展运算符

…运算符可以将数组转换成逗号分隔的参数序列(实参)

const tfboys = ['易烊千玺''王源','王俊凯']
function chunwan(){
    console.log(arguments)
}
chunwan(...tfboys)
//相当于传了三个参数,而不是一个数组

9.1 扩展运算符的应用

9.1.1 数组的合并

const arr1 = [1,2,3]
const arr2 = [4,5,6]
const arr = [...arr1,arr2]

9.1.2 数组的拷贝

浅拷贝

const arr1 = [1,2,3]
const arr2 = [...arr1]

9.1.3 将维数组转换为真正的数组

const divs = document.querySelectorAll('div')
let divArr = [...divs]
console.log(divArr)

10. Symbol数据类型

一种类似于string的数据类型,但是又不同。

JS一共有7种数据类型,分别为USONB:

  • U:undefined
  • S:String Symbol
  • O:Object
  • N:Number Null
  • B:boolean

10.1 Symbol的创建

// 构造函数
let s0 = Symbol()
let s1 = Symbol('1')
let s2 = Symbol('1')
console.log(s1===s2)//false
// Symbol.for创建
let s3 = Symbol.for('1')
let s4 = Symbol.for('1')
console.log(s3===s4);//true

10.2 向对象中添加Symbol类型的属性

    let game = {
      name: "狼人杀",
      [Symbol('say')]: function () {
        console.log('我可以发言')
      },
      [Symbol('explotion')]: function () {
        console.log('我可以自爆')
      }
    }
    console.log(game);

打印的game:

image.png

或者添加同名方法:

    let game = {
      name: "俄罗斯方块",
      up: function () {

      },
      down: function () { }
    }
    let methods = {
      up: Symbol(),
      down: Symbol()
    }
    game[methods.up] = function () {
      console.log('我可以改变形状');
    }
    game[methods.down] = function () {
      console.log('我可以快速下降');
    }
    console.log(game);

打印结果:

image.png

10.3 Symbol的内置属性

这些内置属性是Symbol的属性,同时Symbol.xx又作为对象的属性存在,目的是为了扩展对象的功能。

10.3.1 Symbol.hasInstance 对象类型检测

用于类型检测,检测某个对象是否是某个自定义类的实例,以此来控制instanceof的值。下面这个例子可以判断某个参数是否为非空数组:

    class Arr1 {
      static [Symbol.hasInstance](instance) {
        return Array.isArray(instance) && instance.length > 0
      }
    }
    console.log([] instanceof Arr1)

10.3.2 Symbol.isConcatSpreadable

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

    const arr1 = [1, 2, 3]
    const arr2 = [4, 5, 6]
    arr2[Symbol.isConcatSpreadable] = false
    console.log(arr1.concat(arr2));
    // expected [1,2,3,[4,5,6]]

11. 迭代器

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

  1. Iterator接口主要供for…of消费
  2. 原生具备Iterator接口的数据:
    Array,arguments,Set,Map,String,TypedArray,NodeList
  3. 工作原理:
    const xiyou = ['1', '2', '3', '4']
    // 创建一个指针对象,指向当前数据结构的起始位置
    let iterator = xiyou[Symbol.iterator]()
    // 第一次调用next方法,指针自动指向数据结构的第一个成员
    // 之后的每一次调用next方法指针一直向后移动,直到指向最后一个成员
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());

image.png

可以看到,每次调用next方法都会返回一个包含value和done属性的对象。

也可以通过对象遍历对象中的数组,而不是直接遍历,体现了面向对象的思想:

    const katzchen = {
      name: '猫猫',
      stus: [
        '心心',
        '心宜',
        '丁心宜',
        'dxy'
      ],
      [Symbol.iterator]() {
        let index = 0
        return {
          next: () => {
            if (index < this.stus.length) {
              const result = { value: this.stus[index], done: false }
              index++
              return result
            }
            else {
              return { value: undefined, done: true }
            }
          }
        }
      }
    }
    for (item of katzchen) {
      console.log(item)
    }

打印结果:

image.png

12. 生成器函数

生成器可以和迭代器配合使用来解决回调地狱的问题。

12.1 生成器函数的声明与调用

  • 声明
// 1
function * fnName(){}
// 2
function* fnName(){}
// 3
function *fnName(){}
// 4
function*fnName(){}
  • 调用:
    function* gen() {
    yield '一只没有耳朵'
    console.log(111);
    yield '一只没有尾巴'
    console.log(222);
    yield '真奇怪'
    console.log(333);
    }
    let iterator = gen()
    iterator.next()
    iterator.next()
    iterator.next()
    iterator.next()
    //expected output:111 222 333

yield可以将函数分割成n+1段

12.2 next方法

  • 打印next方法,每次执行next只会执行到这个next对应的yield语句,不会再继续向下执行。
    function* gen() {
    yield '一只没有耳朵'// 第1个next()执行到这里
    console.log(111);
    yield '一只没有尾巴'// 第2个next()执行到这里
    console.log(222);
    yield '真奇怪'// 第3个next()执行到这里
    console.log(333);
    }// 第4个next()执行到这里
    let iterator = gen()
    console.log(iterator.next())
    console.log(iterator.next())
    console.log(iterator.next())
    console.log(iterator.next())

输出:

image.png

  • next方法可以传入实参并获取
    function* gen(arg) {
      console.log(arg);
    }
    let iterator = gen('AAA')
    console.log(iterator.next())

image.png

12.3 yield理解

当调用 next方法时,开始执行,遇到 yield 表达式,就暂停后面的操作,将 yield 后面的表达式的值,作为返回的对象的 value 值.

以下示例会实现每隔一秒分别打印三个不同的数据的功能:

    function getUsers() {
      setTimeout(() => {
        let data = '用户数据'
        // next实参将作为第一个yield语句的返回结果
        iterator.next(data)
      }, 1000)
    }
    function getOrders() {
      setTimeout(() => {
        let data = '订单数据'
        iterator.next()
      }, 1000)
    }
    function getGoods() {
      setTimeout(() => {
        let data = '商品数据'
        iterator.next()
      }, 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

用来解决地狱回调的问题。

13.1 Promise的基本使用

Promise对象构造函数的参数是一个方法,提供了两个函数resolvereject,这两个参数谁放在前面,如果被执行就直接return,不会再继续向下执行。

    const p = new Promise(function (resolve, reject) {
      setTimeout(function () {
        let success = '数据读取成功';
        //设置Promise对象状态为成功
        resolve(success)
        
        let err = '数据读取失败'
        //设置Promise对象状态为失败
        reject(err)
      }, 1000)
    })
    // Promise对象的then方法里面的两个参数也是两个匿名方法,分别是成功和失败的参数。
    p.then((value) => {
      console.log(value);
    }, (reason) => {
      console.log(reason);
    })

13.2 Promise读取文件

// 1.引入fs模块
const fs = require('fs')
// 2.调用方法读取文件
// fs.readFile('./ES6.md', (err, data) => {
//   if (err) throw err
//   console.log(data.toString());
// })
// 3.使用Promise封装
const p = new Promise(function (resolve, reject) {
  fs.readFile('./ES6.md', (err, data) => {
    if (err) reject(err);
    resolve(data)
  })
})
p.then(value => console.log(value.toString()), reason => console.log('读取失败',reason))

13.3 Promise封装AJAX请求

封装前:

    // 创建对象
    const xhr = new XMLHttpRequest();

    // 初始化
    xhr.open('GET', 'https://api.apiopen.top/getJoke')

    // 发送
    xhr.send()

    // 绑定事件,处理相应结果
    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) {
          console.log(xhr.response);
        }
      } else {
        console.log(xhr.status);
      }
    }

封装后:

    const p = new Promise((resolve, reject) => {

      // 创建对象
      const xhr = new XMLHttpRequest();

      // 初始化
      xhr.open('GET', 'https://api.apiopen.top/getJoke')

      // 发送
      xhr.send()

      // 绑定事件,处理相应结果
      xhr.onreadystatechange = function () {
        // console.log(xhr);
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            resolve(xhr.response)
          } else {
            reject('请求失败');
          }
        }
      }
    })

    p.then(function (value) {
      console.log(value)
    },
      function (reason) {
        console.log(reason)
      })

扫盲:
XMLHttpRequest.readyState 属性返回一个 XMLHttpRequest 代理当前所处的状态。一个 XHR 代理总是处于下列状态中的一个:

image.png

所以同一次请求可能在不同的时刻经历过XMLHttpRequest.readyState===2,3,4的情况。所以这个自定义属性不应该写成这样:

    xhr.onreadystatechange = function () {
        // console.log(xhr);
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            resolve(xhr.response)
          } 
        }
        else {
            reject('请求失败');
          }
      }

这样会打印出两个请求失败和一个成功后的response。

  • XMLHttpRequest的MDN : https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest

13.4 then方法

13.4.1 返回的Promise对象的状态

调用then方法,返回值的promise对象的值就是return的值(或是Promise的参数)

  1. 如果回调函数返回的是非Promise类型的数据,状态为成功
  2. 如果是Promise对象,看对象的状态,如果为resolve则为成功,如果为reject则为失败
  3. 如果抛出错误则Promise对象状态一定是失败

三种情况的示例:

    const p = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('用户数据')
      }, 2000)
    })
    let result = p.then(value => {
      console.log(value)
      // 1. 非Promise类型
      // return 123;
      // 2. Prmise类型
      // return new Promise((resolve,reject)=>{
      //   resolve('ok')
      //   reject('error')
      // })
      // 3.抛出错误
      // throw '出错啦!'
    }, reason => {
      console.warn(reason)
    })
    console.log(result);

13.4.2 链式调用

then支持链式调用:

p.then((value)=>{},reason=>{}).then((value)=>{},reason=>{})

13.5 catch方法

其实是一个语法糖,相当于then不实现参数中成功的方法。

    const p = new Promise((resolve, reject) => {
      setTimeout(() => {
        reject("出错啦!")
      }, 1000)
    })
    p.catch(reason => {
      console.log(reason);
    })
    // 相当于
    // p.then(_, reason => console.log(reason))

14. Set

一个数据类型,不包括重复的元素,是Objet

基本用法:

    // 声明
    let s = new Set(['大事儿', '小事儿', '好事儿', '坏事儿', '小事儿'])
    
    console.log(s);// ['大事儿', '小事儿', '好事儿', '坏事儿']
    // 添加新元素
    s.add('111')
    // 删除元素
    s.delete('坏事儿')
    // 检测
    s.has('好事儿')
    // 清空
    s.clear()
    // 遍历
    for(let v of s){
      console.log(v);
    }

15. Map

一个数据类型,包括键值对,是Objet,其中key可以是任何数据类型

  • size 返回Map的元素个数
  • set 增加一个新元素,返回当前Map。如:(m.set(‘key’,‘value’))
  • get 返回键名对象的键值
  • has 检测map中是否含有某个元素,返回boolean
  • clear清空集合,返回undefind

16. class类

通过class关键字,可以定义类。这是ES6引入的更加面向对象编程的语法,但是他的大多数功能ES5也可以实现。

16.1 class声明类

    // ES5声明类
    function Phone(brand, price) {
      this.brand = brand
      this.price = price
    }
    Phone.prototype.call = function () {
      console.log('我可以打电话!');
    }
    // 注意,如果不加prototype则是在函数上直接添加属性,在实例化的时候对象不会有这个属性
    // 我们称他为静态属性
    let Huawei = new Phone('华为', 5999)
    Huawei.call()
    console.log(Huawei);
    // ES6声明类
    class Shouji {
      // 构造方法,在new的时候就会执行这个实例对象上的constractor方法
      constructor(brand, price) {
        this.brand = brand
        this.price = price
      }
      //方法必须这样写,不能使用ES5的对象完整形式
      call() {
        console.log('我也可以打电话~');
      }
    }
    let OnePlus = new Shouji("1+", 1999)
    OnePlus.call()
    console.log(OnePlus);

image.png

16.2 constractor定义构造函数初始化

ES5实现继承:

    function Phone(brand, price) {
      this.brand = brand
      this.price = price
    }

    Phone.prototype.call = function () {
      console.log('我可以打电话');
    }

    function smartPhone(brand, price, color, size) {
      Phone.call(this, brand, price)
      this.color = color
      this.size = size
    }
    // 设置子级构造函数的原型
    smartPhone.prototype = new Phone
    // 这行可以不加,不加的话子类就没有原型了
    smartPhone.prototype.constructor = smartPhone

    //声明子类的方法
    smartPhone.prototype.photo = function () {
      console.log('我可以拍照');
    }

    const xiaomi = new smartPhone('小米', 3999, 'blue', '5.1inch')
    console.log(xiaomi);
    xiaomi.call()
    xiaomi.photo()

打印结果:

image.png

16.3 extends继承父类,super调用父级构造方法

ES6实现类继承:

    class Phone {
      constructor(brand, price) {
        this.brand = brand
        this.price = price
      }
      call() {
        console.log('我可以打电话');
      }
    }

    class SmartPhone extends Phone {
      constructor(brand, price, color, size) {
        // 相当于
        // Phone.call(this,brand,price)
        super(brand, price)
        this.color = color
        this.size = size
      }
      photo() {
        console.log('我可以拍照');
      }
      playGame(){
        console.log('我可以玩游戏');
      }
    }
    const xiaomi = new SmartPhone('小米', 3999, 'blue', '5.1inch')
    console.log(xiaomi);
    xiaomi.call()
    xiaomi.photo()

image.png

16.4 父类方法可以重写

子类直接在方法里面写父类同名方法就可以实现父类方法的重写,不再赘述。

16.5 getter和setter

    class Phone {
     
      get price() {
        console.log('价格属性被读取了');
    return '520'
      }
      set price(newVal) {
        console.log('价格属性被修改了');
      }
    }
   
    let s = new Phone()

    console.log(s.price);
    s.price = 'free'

image.png

17. 数值扩展

17.1 Number.EPSILON是JS最小精度

    function equal(a, b) {
      return Math.abs(a - b) < Number.EPSILON ? true : false

    }
    console.log(0.1 + 0.2 === 0.3);//false
    console.log(equal(0.1 + 0.2, 0.3));//true

17.2 进制运算

  • 2进制:0b开头
  • 8进制:0o开头
  • 16进制:0x开头

17.3 其他

  • Number.trunc:将数字的小数部分抹掉
  • Math.sign 判断一个数是正数(return 1)负数(return -1)还是0(return 0)

18. ES5-ES6对象方法拓展

18.1 Object.is判断两个值是否完全相等,如果是对象的话,必须是同一个引用。

Object.is('foo', 'foo');     // true
Object.is(window, window);   // true

Object.is('foo', 'bar');     // false
Object.is([], []);           // false

var foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo);         // true
Object.is(foo, bar);         // false

Object.is(null, null);       // true

// 特例
Object.is(0, -0);            // false
Object.is(0, +0);            // true
Object.is(-0, -0);           // true
Object.is(NaN, 0/0);         // true
Object.is(NaN,NaN)           // true

18.2 Object.assign 对象的合并

Object.assign(Object1,Object2)

如果属性两个对象存在同名属性,则会用Object2的属性覆盖Object1的属性。不同名的互不覆盖。

18.3 Object.setPrototypeOf设置原型对象

    const school = {
      name: '山东大学'
    }
    const cities = {
      xiaoqu: ['济南', '威海', '青岛']
    }
    // 设置school的原型为cities
    Object.setPrototypeOf(school, cities);
    console.log(school);
    // 获取原型
    console.log(Object.getPrototypeOf(school));

image.png

19. 模块化

通过模块化,可以提高项目的复用性,降低维护成本等。

19.1 模块暴露语法汇总

19.1.1 分别暴露

export let school = '山东大学'
export let geli = function(){
    console.log('隔离中')
}

19.1.2 统一暴露

let school = '山东大学'
let geli = function(){
    console.log('隔离中')
}
export {school,geli}

19.1.3 默认暴露(VUE常用)

export default{
    school:'山东大学',
    geli:function(){
        console.log('隔离中')
    }
}

19.2 模块引入语法汇总

19.2.1 通用的导入方式

import * as m1 from "./src/m1.js"

19.2.2 解构赋值的形式

这种形式可以直接使用schoolgeli这两个变量。

import {school,geli} from "./src/m1.js"

如果有重名的变量,可以使用别名的方式:

import {school,geli} from "./src/m1.js"
import {school as university} from "./src/m2.js"

对于默认暴露,这里引入的是default属性的变量,但是不能直接使用default,必须起一个别名采用如下固定格式:

import {default as m3} from "./src/m3.js"

19.3.3 简便形式(only默认暴露)

只针对默认暴露!!

import m3 from "./src/m3.js"

19.3 入口文件方式

使用入口文件进行引入(app.js),然后在html中引用:

  <script src="./../js/app.js" type="module"></script>

20. ES7新特性

20.1 **幂运算

console.log(2**10)//1024

21. ES8新特性

21.1 async

会返回一个promise对象,对象的状态取决于return的值:

  • 若返回的结果不是一个Promise类型的对象,则async函数返回的promise对象的状态都是resolved.
  • 抛出错误的话Promise对象的状态为rejected.
  • 若返回的结果是一个Promise类型的对象,取决于返回的Promise对象的状态.
    async function fn() {
      return new Promise((resolve, reject) => {
        // resolve('成功的数据')
        reject('失败的数据')
      })
    }
    
    const result = fn();
    console.log(result);

image.png
如果调用then,则then调用的回调函数取决于Promise的状态.

21.2 await

await必须写在async函数中,其右测表达书一般为primise对象,返回的是promise成功的值,如果promise失败了就会抛出异常,需要通过try…catch处理.

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

21.3 async await 读取文件

let fs = require('fs')
 function readMd() {
  return new Promise((resolve, reject) => {
    fs.readFile("./../md/ES6.md", (err, data) => {
      if (err) reject(err)
      resolve(data)
    })
  })
}
async function main() { 
  let data = await readMd()
  console.log(data.toString());
}
main()

21.4 async,await封装ajax请求

首先用promise对AJAX请求进行封装:

    function sendAJAX(url) {
      let xml = new XMLHttpRequest()
      xml.open('get', url)
      xml.send()
      return new Promise((resolve, reject) => {
        xml.onreadystatechange = function () {
          if (xml.readyState === 4) {
            if (xml.status >= 200 && xml.status < 300) {
              resolve(xml.response)

            } else {
              reject(xml.status)
            }
          }
        }
      })
    }

调用then方法:

    const result=sendAJAX('https://api.apiopen.top/getJoke')
    .then(res=>console.log(res),err=>console.log(err))

或者使用async&await:

    async function main() {
      let result = await sendAJAX("https://api.apiopen.top/getJoke")
      console.log(result);
    }
    main()

都可以打印响应体或者失败的状态码.

22. ES8对象方法拓展

首先创建一个对象:

    const school = {
      name: '山东大学',
      cities: ['济南', '威海', '青岛'],
      xueke: ['理科', '工科', '文科']
    }

22.1 Object.values()和Object.entries()

应用实例,注意2,3是ES8的新特性

    // 1.获取对象所有的键
    console.log(Object.keys(school));
    // 2.获取对象所有的值
    console.log(Object.values(school));
    // 3.entries:获取键值
    console.log(Object.entries(school));
    // 4.创建map
    console.log(new Map(Object.entries(school)));

打印结果:

image.png

22.2 Object.getOwnPropertyDescriptors获取对象属性的描述对象

console.log(Object.getOwnPropertyDescriptors(school));

打印结果:

image.png

23. ES9

23.1 rest参数

rest参数可以将函数实参中剩下的参数存到一个对象里,例如

    function connect({ host, port, ...user }) {
      console.log(host);
      console.log(port);
      console.log(user);
    }
    connect({
      host: '127.0.0.1',
      port: 3306,
      username: 'dxy',
      password: '123456'
    })

image.png

23.2 扩展运算符

可以实现对象的合并.

    const lifeOne = {
      o: '吃饭'
    }
    const lifeTwo = {
      t: '睡觉'
    }
    const lifeThree = {
      c: '写代码'
    }
    const life = { ...lifeOne, ...lifeTwo, ...lifeThree }
    console.log(life);
    // {o: '吃饭', t: '睡觉', c: '写代码'}

24. ES10新特性

24.1 Object.fromEntries()

可以将二维数组或Map转换成对象

      // 二维数组,将二维数组转化为对象
    let arr = [['school', '山东大学'], ['compus', '软件学院,微电子学院']]
  
    const result = Object.fromEntries(arr)
    console.log(result);
  
    // Map
    const m=new Map()
    m.set('school','山东大学')
    m.set('compus','软件学院,微电子学院')
    console.log(Object.fromEntries(m));

image.png
和Object.entries()互为逆运算

    // 二维数组,将二维数组转化为对象
    let arr = [['school', '山东大学'], ['compus', '软件学院,微电子学院']]

    const result = Object.fromEntries(arr)
    console.log(result);

    // 对比Object.entries()
    const arr1 = Object.entries(result)
    console.log(arr1);

image.png

24.2 字符串方法 trimStart()和trimEnd()

let str='  iloveyou   '

console.log(str);
// 去掉开头空格
console.log(str.trimStart());
// 去掉结尾空格
console.log(str.trimEnd());
// 去掉所有空格
console.log(str.trim());

24.3 数组方法 flat()和flatMap()

flat()可以将数组从高维转为低维,默认参数是1,即维度-1,如果不是1则需要填写参数,参数为目前维度-目标维度,是一个Number。

map()方法如果返回的是一个高维数组,也可以使用flatMap()将Map()转化成一个低维数组。

24.4. 私有属性

在类的前面加#即可制定这个属性为私有属性,这个属性不能在对象中直接调用,要通过类的方法调用这个对象的私有属性,体现了面向对象的思想。

    class Person {
      name;
      #age;
      #weight;
      constructor(name, age, weight) {
        this.name = name
        this.#age = age
        this.#weight = weight
      }
      get() {
        console.log(this.name);
        console.log(this.#age);
        console.log(this.#weight);
      }
    }
    const girl = new Person('小红', 21, '50kg')
    // 通过类的方法打印才能打印出来
    girl.get()
    // console.log(girl.#age);
    // Uncaught SyntaxError: Private field '#age' must be declared in an enclosing class
    

24.5 Promise.Allsettled()方法

可以一次接收多个Promise对象(用数组排列),无论每一个Promise结果如何,其返回的Promise总是resolved,和all不一样,all只在每一个Promise都为resolved时候返回的才是才是resolve。

24.6 可选链操作符

可以用?.代替&&进行链式判断,举一个传参的例子,如果我们行要访问对象的某个参数,首先需要检验它在不在,如果不在会返回undefined,不会报错:

    function main(config) {
      //相当于 const dbHost = config && config.db && config.db.host;
      const dbHost = config?.db?.host;
      console.log(dbHost);
    }
    main({
      db: {
        host: '192.127.1.100',
        username: 'root'
      },
      cache: {
        host: '192.127.1.200',
        username: 'admin'
      }
    })
    //192.127.1.100

24.7 动态引入

使用import()动态引入另一个模块,返回的是一个promise对象,只需要调用这个对象的方法即可。

举例:

第一步:在html中引入app.js,添加按钮写id:

<body>
  <button id="btn">点击</button>
  <script src="./../js/app.js" type="module">

  </script>

</body>

第二步:在app.js获取id:

const btn = document.getElementById('btn')

第三步:在btn.js写一个点击事件和方法并暴露出去:

export function hello() {
  alert('Hello')
}

第四步:在app.js动态引入并使用btn.js的函数:

btn.onclick = function () { 
  import('./btn.js').then(module => {
    module.hello()
  })
}

点击按钮就会触发alert事件:
image.png

24.8 BigInt类型

用处不多,主要注意声明的时候在数字后面加n就会检测出是bigint类型了,而且两个BigInt不能喝Number运算,只能和BigInt运算。

最后

以上就是忐忑猎豹为你收集整理的ES6学习笔记(包括ES6-ES11常用特性)的全部内容,希望文章能够帮你解决ES6学习笔记(包括ES6-ES11常用特性)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部