ES6-ES11



ECMAScript 是由ECMA国际通过 ECMA-262标准化的脚本标准化的脚本程序设计语言,Ecma 国际制定了许多标准,而 ECMA-262 只是其中的一个,从 ES6 开始,每年发布一个版本,版本号比年份最后一位大 1,ECMA-262至今已发展到了第十一版。

ECMA

  • ECMA(European Computer Manufacturers Association)

    • 中文名称为欧洲计算机制 造商协会,这个组织的目标是评估、开发和认可电信计算机标准。1994年后该组织改名为 ECMA国际
  • 谁在维护 ECMA-262

    • TC39(Technical Committee 39)是推进 ECMAScript 发展的委员会。其会员都是公司(其中主要是浏览器厂商,有苹果、谷歌、微软、因特尔等)。TC39 定期召开会议,会议由会员公司的代表与特邀专家出席
  • 兼容性

  • http://kangax.github.io/compat-table/es6/ 可查看兼容性

  • 红色表示不兼容,绿色表示兼容

ES6

  • ES6 的版本变动内容最多,具有里程碑意义
  • ES6 加入许多新的语法特性,编程实现更简单、高效

let关键字

  • let 关键字用来声明变量,使用 let 声明的变量有几个特点:
  1. 不允许重复声明
  2. 块级作用域
  3. 不存在变量提升,不允许在变量声明之前使用
  4. 不影响作用域链的效果
  • 应用场景:以后声明变量使用 let 就对了

const 关键字

  • const 关键字用来声明常量,const 声明有以下特点
  1. 声明必须赋初始值
  2. 标识符一般为大写
  3. 不允许重复声明
  4. 值不允许修改
  5. 块级作用域
  • 注意: 对象属性修改和数组元素变化不会触发const错误,因为地址没有改变
  • 应用场景:声明对象类型使用 const,非对象类型声明选择 let

变量的解构赋值

  • ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    //数组的解构赋值
    const arr = ['张学友', '刘德华', '黎明', '郭富城'];
    let [zhang, liu, li, guo] = arr;


    //对象的解构赋值
    const lin = {
    name: '林志颖',
    tags: ['车手', '歌手', '小旋风', '演员']
    };
    let {name, tags} = lin;


    //复杂解构
    let wangfei = {
    name: '王菲', age: 18,
    songs: ['红豆', '流年', '暧昧', '传奇'],
    history: [
    {name: '窦唯'},
    {name: '李亚鹏'},
    {name: '谢霆锋'}
    ]};
    let {songs: [one, two, three], history: [first, second, third]} =wangfei;

    模板字符串

  • 模板字符串(template string)是增强版的字符串,用反引号(`)标识,特点:
    1) 字符串中可以出现换行符
    2) 可以使用 ${xxx} 形式输出变量
    1
    2
    3
    // 变量拼接
    let lovest = '魏翔';
    let out = `${lovest}是我心目中最搞笑的演员!!`;

简化对象写法

  • ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    let name = 'xxx';
    let change = function(){
    console.log('xxx!');
    }

    const school = {
    name,
    change,
    improve(){ //可以省略function
    console.log("xxx");
    }
    }

箭头函数

  • ES6 允许使用「箭头」( => )定义函数。
    箭头函数的注意点:
    1) 如果形参只有一个,则小括号可以省略
    2) 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果
    3) this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值
    4) 箭头函数不能作为构造函数实例化
    5) 不能使用 arguments
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    /**
    * 1. 通用写法
    */
    let fn = (arg1, arg2, arg3) => {
    return arg1 + arg2 + arg3;


    /**
    * 2. 省略小括号的情况, 当形参有且只有一个的时候
    */
    let fn2 = num => {
    return num * 10;


    /**
    * 3. 省略花括号的情况,当代码体只有一条语句的时候, 此时 return 必须省略,语句的执行结果就是函数的返回值
    */
    let fn3 = score => score * 20;


    /**
    * 4. this 指向声明时所在作用域中 this 的值
    */
    let fn4 = () => {
    console.log(this);
    }
  • 注意:箭头函数不会更改 this 指向,用来指定回调函数会非常合适
  • ES6 允许给函数参数赋值初始值
    1. 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)
    2. 默认值还可以与解构赋值结合

rest 参数

  • ES6 引入 rest 参数(…args),用于获取函数的实参,用来代替 arguments
    1
    2
    3
    4
    5
    6
    7
    rest 参数必须要放到参数最后
    function fn(a,b,...args){
    console.log(a);
    console.log(b);
    console.log(args);
    }
    fn(1,2,3,4,5,6);

spread 扩展运算符

  • 扩展运算符(spread)也是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包
    1. 可以合并数组
    2. 可以克隆数组
    3. 将伪数组转为真正的数组
      1
      2
      3
      4
      5
      6
      7
      8
      9
      // 『...』 扩展运算符能将『数组』转换为逗号分隔的『参数序列』
      //声明一个数组 ...
      const tfboys = ['易烊千玺','王源','王俊凯'];
      // => '易烊千玺','王源','王俊凯'
      // 声明一个函数
      function chunwan(){
      console.log(arguments);
      }
      chunwan(...tfboys);// chunwan('易烊千玺','王源','王俊凯')

Symbol

  • ES6 引入了一种新的原始数据类型 Symbol, 表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
    Symbol 特点
    1) Symbol 的值是唯一的,用来解决命名冲突的问题
    2) Symbol 值不能与其他数据进行运算
    3) Symbol 定义的对象属性不能使用 for…in 循环遍历, 但是可以使用
    Reflect.ownKeys 来获取对象的所有键名
  • js数据类型:undefined string symbol object null number boolean

Symbol 内置值

  • 除了定义自己使用的 Symbol 值以外,ES6 还提供了11 个内置的Symbol 值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行

迭代器

  • 遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作
    1) ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费
    2) 原生具备 iterator 接口的数据(可用 for of 遍历)
    • Array
    • Arguments
    • Set
    • Map
    • String
    • TypedArray
    • NodeList
      3) 工作原理
    • 创建一个指针对象,指向当前数据结构的起始位置
    • 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
    • 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
    • 每调用 next 方法返回一个包含 value 和 done 属性的对象
  • 注: 需要自定义遍历数据的时候,要想到迭代器

生成器

  • 生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同
    1
    2
    3
    4
    5
    6
    function * gen(){
    yield '一只没有耳朵';
    yield '一只没有尾巴'; return '真奇怪';
    }
    let iterator = gen(); console.log(iterator.next()); console.log(iterator.next());
    console.log(iterator.next());
    代码说明:
    1) *的位置没有限制
    2) 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到
    yield 语句后的值
    3) yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next
    方法,执行一段代码
    4) next 方法可以传递实参,作为 yield 语句的返回值

Promise

  • Promise 是 ES6 引入的异步编程的新解决方案。语法上Promise 是一个构造函数, 用来封装异步操作并可以获取其成功或失败的结果。
    1) Promise 构造函数: Promise (excutor) {}
    • promise (function(resolve,reject){});
      2) Promise.prototype.then 方法
    • then(function(){value},function(reason){})
    • 调用 then 方法 then方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果决定
      • 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值
      • 如果是promise对象,promise返回的对象的状态就决定了then方法返回的promise的状态
        3) Promise.prototype.catch 方法

Set

  • ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,集合的属性和方法:
    1) size 返回集合的元素个数
    2) add 增加一个新元素,返回当前集合
    3) delete 删除元素,返回 boolean 值
    4) has 检测集合中是否包含某个元素,返回 boolean 值
    5) clear 清空集合,返回 undefined

Map

  • ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键” 的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。Map 的属性和方法:
    1) size 返回 Map 的元素个数
    2) set 增加一个新元素,返回当前 Map
    3) get 返回键名对象的键值
    4) has 检测 Map 中是否包含某个元素,返回 boolean 值
    5) clear 清空集合,返回 undefined

class 类

  • ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法塘,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
    知识点:
    1) class 声明类
    2) constructor 定义构造函数初始化
    3) extends 继承父类
    4) super 调用父级构造方法
    5) static 定义静态方法和属性
    6) 父类方法可以重写

数值扩展

  1. Number.EPSILON 是 JavaScript 表示的最小精度

    • 0.1+0.2===0.3不成立,因为浮点数运算是由误差的
    • EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16
    • 用EPSILON表示js运算的最小精确度
  2. 二进制和八进制

    • ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示
  3. Number.isFinite() 与 Number.isNaN()

    • Number.isFinite() 用来检查一个数值是否为有限的
    • Number.isNaN() 用来检查一个值是否为 NaN
  4. Number.parseInt() 与 Number.parseFloat()字符串转整数

    • ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变
  5. Math.trunc

    • 用于去除一个数的小数部分,返回整数部分
  6. Number.isInteger

    • Number.isInteger() 用来判断一个数值是否为整数
  7. Math.sign

    • 判断一个数到底为正数 负数 还是零

对象扩展

  • ES6 新增了一些 Object 对象的方法
    1) Object.is比较两个值是否严格相等,与『===』行为基本一致(+0 与 NaN)
    2) Object.assign 对象的合并,将源对象的所有可枚举属性,复制到目标对象
    3) proto 、setPrototypeOf、 setPrototypeOf 可以直接设置对象的原型

模块化

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

1.模块化的好处

  • 模块化的优势有以下几点:
    1) 防止命名冲突
    2) 代码复用
    3) 高维护性
  1. 模块化规范产品
  • ES6 之前的模块化规范有:
    1) CommonJS => NodeJS、Browserify
    2) AMD => requireJS
    3) CMD => seaJS
  1. ES6 模块化语法
  • 模块功能主要由两个命令构成:export 和 import
    • export 命令用于规定模块的对外接口
    • import 命令用于输入其他模块提供的功能
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      import:
      1. 通用的导入方式
      引入 m1.js 模块内容
      import * as m1 from "./src/js/m1.js";
      //引入 m2.js 模块内容
      import * as m2 from "./src/js/m2.js";
      //引入 m3.js
      import * as m3 from "./src/js/m3.js";

      2. 解构赋值形式
      import {school, teach} from "./src/js/m1.js";
      import {school as guigu, findJob} from "./src/js/m2.js";
      import {default as m3} from "./src/js/m3.js";

      3. 简便形式 针对默认暴露
      import m3 from "./src/js/m3.js";
      console.log(m3);
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      export:
      //分别暴露
      export let school = 'xxx';
      export function teach() {
      console.log("xxx");
      }

      //统一暴露
      let school = 'xxx';
      function teach(){
      console.log("xxx");
      }
      export {school, teach};

      //默认暴露
      export default {
      school: 'xxx',
      teach: function(){
      console.log("xxx");
      }
      }

ES7

  1. Array.includes()

    • Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值
  2. 指数操作符

    • 在 ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同

ES8

  1. async 和 await

    • async 和 await 两种语法结合可以让异步代码像同步代码一样
    1. async 函数
      • async 函数的返回值为 promise 对象,
      • promise 对象的结果由 async 函数执行的返回值决定
    2. await 表达式
      • await 必须写在 async 函数中
      • await 右侧的表达式一般为 promise 对象
      • await 返回的是 promise 成功的值
      • await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理
  2. Object.values 和 Object.entries

    • Object.values()方法返回一个给定对象的所有可枚举属性值的数组
    • Object.entries()方法返回一个给定对象自身可遍历属性 [key,value] 的数组
  3. Object.getOwnPropertyDescriptors

    • 该方法返回指定对象所有自身属性的描述对象

ES9

  1. Rest/Spread 属性
  • Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function connect({host, port, ...user}) {
    console.log(host);
    console.log(port);
    console.log(user);
    }

    connect({
    host: '127.0.0.1',
    port: 3306,
    username: 'root',
    password: 'root',
    type: 'master'
    });
  1. 正则表达式命名捕获组
  • ES9 允许命名捕获组对捕获的结果进行命名,这样获取捕获结果可读性更强
    1
    2
    3
    4
    5
    6
    7
    8
    let str = '<a href="http://www.atguigu.com"></a>'; 
    const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;

    const result = reg.exec(str);

    console.log(result.groups.url);

    console.log(result.groups.text);
  1. 正则表达式反向断言
  • ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //声明字符串
    let str = 'JS5211314 你知道么 555 啦啦啦';

    //正向断言
    const reg = /\d+(?=啦)/;
    const result = reg.exec(str);

    //反向断言
    const reg = /(?<=么)\d+/;
    const result = reg.exec(str);
    console.log(result);
  1. 正则表达式 dotAll 模式
  • 正则表达式中点 . 匹配除回车外的任何单字符,标记『s』改变这种行为,允许行终止符出现

ES10

  1. Object.fromEntries
    • 将二维数组转化为对象,与entries作用相反
  2. trimStart 和 trimEnd
    • trimStart负责清除字符串左侧空白
    • trimEnd负责清除字符串右侧空白
  3. Array.flat() 与 flatMap
    • flat()将多维数组转化为低维数组
    • flatMap把Map的结果做一个维度降低,是flat和map操作的结合体
  4. Symbol.prototype.description
    • 获取symbol的描述字符串

ES11

  1. 类的私有属性

    • 私有属性前要加#
  2. String.prototype.matchAll

    • 用来得到正则批量匹配的结果
  3. Promise.allSettled

    • 接受一个promise数组,返回一个成功的结果,成功的值是每一个promise对象的状态和结果
  4. 可选链操作符?.

    • xxx1?.xxx2?.xxx3如果有xxx1才会读取后面的xxx2以此类推
  5. 动态 import 导入

  6. globalThis 对象

    • 始终指向全局对象