ES6-ES11最通俗易懂保姆级的笔记!人见人爱,花见花开。赶快动起你发财的小手收藏起来吧,满满的干货,你值得拥有!!

1.  ES6

1.1  let变量声明以及声明特性

声明变量

let a;
let b, c, e;
let f = 100,
g = "红石榴21",
h = [];

特性:

  • 变量不能重复声明
let start = "许巍";
let start = "刀郎"; // 报错
  • 块级作用域 全局、函数、eval
{
   let str = "红石榴21"
}
console.log(str); // str is not defined
不仅仅针对花括号,if else while for中都是块级作用域
  • 不存在变量提升
console.log(song);
let song = "罗刹海市";  // Cannot access 'song' before initialization
  • 不影响作用域链
{
  let school = "国防科技大学";
  function fn() {
    console.log(school); // 国防科技大学
  }
  fn();
}

 案例

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>let经典案例实践</title>
    <link
      crossorigin="anonymous"
      href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css"
      rel="stylesheet"
    />
  </head>
  <body>
    <div class="container">
      <h2 class="page-header">点击切换颜色</h2>
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
    </div>
    <style>
      .item {
        width: 100px;
        height: 50px;
        border: solid 1px rgb(42, 156, 156);
        float: left;
        margin-right: 10px;
      }
    </style>
    <script>
      let items = document.getElementsByClassName("item");
      // for (var i = 0; i < items.length; i++) {
      //   items[i].onclick = function () {
      //     this.style.background = "pink"; // for循环中,不使用let声明
      //   };
      // }
      for (let i = 0; i < items.length; i++) {
        items[i].onclick = function () {
          items[i].style.background = "pink"; // for循环中,使用let声明
        };
      }
    </script>
  </body>
</html>

1.2  const声明常量以及特点

常量声明
const SCHOOL = "西南石油大学";
特性:
  • 一定要赋初始值
 const A; // 报错
  • 一般变量使用大写(潜规则)
const A = 100;
  • 常量的值不能被修改
SCHOOL = "国防科技大学";
console.log(SCHOOL); // Assignment to constant variable.
  • 块级作用域
{
  const YWZQ = "go";
}
console.log(YWZQ); // YWZQ is not defined
  • 对于数组和对象元素的修改,不算对常量的修改,不会报错
const LIKE = ["HG", "MC", "LZZ"];
LIKE.push("ZZC");
console.log(LIKE); // ['HG', 'MC', 'LZZ', 'ZZC']

1.3  变量的解构赋值

ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。
  • 数组结构赋值
const F4 = ["小沈阳", "赵四", "刘能", "宋小宝"];
let [xiao, zhao, liu, song] = F4;
console.log(xiao); // 小沈阳
console.log(zhao); // 赵四
console.log(liu); // 刘能
console.log(song); // 宋小宝
  • 对象结构赋值
const zhao = {
  name: "赵本山",
  age: "65",
  xiaoping: function () {
    console.log("我会演小品");
  },
};
let { name, age, xiaoping } = zhao;
console.log(name); // 赵本山
console.log(age); // 65
console.log(xiaoping); // 输出ƒ(){}
xiaoping(); // 我会演小品
如果不用结构的形式
console.log(zhao.name);
console.log(zhao.age);
zhao.xiaoping();
zhao.xiaoping();

1.4  模板字符串

ES6 引入新的声明字符串的方式 『``』 '' ""
  • 声明变量
let str = `今天天气有点热啊`;
console.log(str);
  • 内容可以直接出现换行符
let str =
  "<ul>" + "<li>张三</li>" + "<li>李四</li>" + "<li>王五</li>" + "</ul>"; // 之前的写法
let str = 
  `<ul>
    <li>张三1</li>
    <li>李四2</li>
    <li>王五3</li>
  </ul>`;
document.getElementById("appID").innerHTML = str;
  • 字符串的拼接
let str = "许巍"; 
let lovest = `我喜欢${str}的歌,名字叫做<<蓝莲花>>。`;
console.log(lovest);
1.5  对象的简化写法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。
这样的书写更加简洁
let name = "红石榴21";
let change = function () {
  console.log("我想改变世界!!");
};
const dream = {
  name,
  change,
  // improve: function () {
  //   console.log("我又get到了新的技能!");
  // },
  // 简写形式
  improve() {
    console.log("hahaha");
  },
};
dream.change();
dream.improve();

1.6  箭头函数以及声明特点

ES6 允许使用「箭头」(=>)定义函数。
声明一个函数
let fn = function() {}
let fn = function (a, b) {
    return a + b;
};
// 调用函数
let result = fn(1, 2);
console.log(result); // 3

特性:

  • this 是静态的,this 始终指向函数声明时所在作用域下的 this 的值
function getName() {
  console.log(this.name);
}
let getName2 = () => {
  console.log(this.name);
};
// 设置 window 对象的name 属性
window.name = "红石榴21";
const school = {
  name: "博商学院",
};
// 直接调用
getName(); // 红石榴21
getName2(); // 红石榴21
// call 方法调用
getName.call(school); // 博商学院
getName2.call(school); // 红石榴21
  • 不能作为构造函数实例化对象
let Person = (name, age) => {
  this.name = name;
  this.age = age;
};
let me = new Person("hong", 18);
console.log(me); // Person is not a constructor
  • 不能使用 arguments 变量
let fn = () => {
  console.log(arguments);
};
fn(1, 2, 3); // arguments is not defined
  • 箭头函数的简写
// 1) 省略小括号,当形参有且只有一个的时候
let add = n => {
  return n + n;
};
console.log(add(9)); // 18
// 2) 省略花括号,当代码体只有一条语句的时候,此时 return 必须省略
// 而且语句的执行结果就是函数的返回值
let pow = (n) => n * n;
console.log(pow(9)); // 81

 箭头函数的实践与应用场景

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>箭头函数的实践与应用场景</title>
  </head>
  <body>
    <div id="add"></div>
    <style>
      #add {
        width: 200px;
        height: 200px;
        background: #58a;
      }
    </style>
    <script>
      // 需求-1  点击 div 2s 后颜色变成『粉色』
      // 获取元素
      let add = document.getElementById("add");
      //绑定事件
      add.addEventListener("click", function () {
        // 1、setTimeout未使用箭头函数
        //保存 this 的值
        // let _this = this;
        // let that = this;
        // let self = this;
        // setTimeout(function () {
        //   _this.style.background = "pink";
        // }, 2000);
        // 2、setTimeout使用箭头函数, this 是静态的
        setTimeout(() => {
          this.style.background = "pink";
        }, 2000);
      });
      // 需求-2  从数组中返回偶数的元素
      const arr = [1, 2, 4, 6, 10, 13];
      // const result = arr.filter(function (item) {
      //   if (item % 2 === 0) {
      //     return true;
      //   } else {
      //     return false;
      //   }
      // });
      // const result = arr.filter((item) => {
      //   if (item % 2 === 0) {
      //     return true;
      //   } else {
      //     return false;
      //   }
      // });
      // 简写形式
      const result = arr.filter((item) => item % 2 === 0);
      console.log(result);
      // 箭头函数适合与 this 无关的回调,定时器,数组的方法回调
      // 箭头函数不适合与 this 有关的回调,事件回调,对象的方法
    </script>
  </body>
</html>
1.7  函数参数的默认值设置
ES6 允许给函数参数赋值初始值
  • 形参初始值 具有默认值的参数,一般位置要靠后(潜规则)
function add(a, b, c) {
  return a + b + c;
}
let result = add(1, 2, 3);
console.log(result); // 6
// 设置默认值
function add(a, b, c = 4) {
  return a + b + c;
}
let result = add(1, 2);
console.log(result);  // 7
  • 与结构赋值结合
function connect({ host, username, password, port }) {
  console.log(host);
  console.log(username);
  console.log(password);
  console.log(port);
}
connect({
  host: "127.0.0.1",
  username: "admin",
  password: "admin",
  port: 80,
});
1.8  rest参数
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
ES5 获取实参的方式
function date() {
  console.log(arguments);
}
date("俞老师", "王老师", "顾老师");

rest 参数

function date(...args) {
  console.log(args); // [俞老师", "王老师", "顾老师] 变成数组就可以使用 filter、some、every、map
}
date("俞老师", "王老师", "顾老师");
rest 参数必须要放到参数最后
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);

1.9  扩展运算符的介绍

『...』 扩展运算符能将『数组』转换为逗号分隔的『参数序列』
// 声明一个数组
const tfbody = ["朴树", "许巍", "刀郎"];
// 声明一个函数
function likeSinger() {
  console.log(arguments);
}
likeSinger(...tfbody);
console.log(tfbody);

输出结果

 扩展运算符的应用

  • 数组的合并
const siDaTianWang = ["刘德华", "张学友", "郭富城", "黎明"];
const xiaoHuDui = ["吴奇隆", "陈志朋", "苏有朋"];
// const zuHe = siDaTianWang.concat(xiaoHuDui); // 使用concat实现数组拼接
// console.log(zuHe); // ["刘德华", "张学友", "郭富城", "黎明","吴奇隆", "陈志朋", "苏有朋"]
const zuHe = [...siDaTianWang, ...xiaoHuDui];
console.log(zuHe); // ["刘德华", "张学友", "郭富城", "黎明","吴奇隆", "陈志朋", "苏有朋"]
  • 数组的克隆
const ziMu = ["A", "B", "C"];
const newArr = [...ziMu];
console.log(ziMu); // ["A", "B", "C"]
console.log(newArr); // ["A", "B", "C"]
  • 将伪数组转为真正的数组
const divS = document.querySelectorAll("div");
const divArr = [...divS];
console.log(divArr);

输出结果

1.10.1  Symbol的介绍与创建
  • 创建Symbol
let s = Symbol();
console.log(s, typeof s); // Symbol() 'symbol'
let s2 = Symbol("嘀嘀咕咕");
let s3 = Symbol("嘀嘀咕咕");
console.log(s2, typeof s2); // Symbol(嘀嘀咕咕) 'symbol'
console.log(s2 === s3); // false
  • Symbol.for 创建
let s4 = Symbol.for("我的心思");
let s5 = Symbol.for("我的心思");
console.log(s4); // Symbol(我的心思)
console.log(s4 === s5); // true
  • 不能与其他数据进行运算
let result = s + 100; // Cannot convert a Symbol value to a number
let result = s > 100; // Cannot convert a Symbol value to a number
let result = s + s; // Cannot convert a Symbol value to a number
// USONB you are so niubility
// u   undefined
// s   string   symbol
// o   object
// n   null   number
// b   boolean 

1.10.2 对象添加Symbol类型的属性

向对象中添加方法 up down
let game = {
  name: "学爸",
  up: function () {},
  down: function () {},
};

// 声明一个对象
let methods = {
  up: Symbol(),
  down: Symbol(),
};
// console.log(methods);

game[methods.up] = function () {
  console.log("我可以改变世界!");
};

game[methods.down] = function () {
  console.log("海鲜都留给小日子吃吧!");
};
console.log(game);

输出结果

let phws = {
  name: "排核污水",
  [Symbol("say")]: function () {
    console.log("打断小日子的狗腿");
  },
  [Symbol("woof")]: function () {
    console.log("小日子公开食海鲜,真香");
  },
};
console.log(phws);

输出结果

1.10.3  Symbol的内置属性

  • Symbol.hasInstance
当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法
class Person {
  static [Symbol.hasInstance](param) {
    console.log(param);
    console.log("我被用来检测类型了");
    return true;
  }
}
let o = {};
console.log(o instanceof Person);
  • Symbol.isConcatSpreadable
对象的 SymbolisConcatSpreadable 属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。
const arr = [1, 2, 3];
const arr2 = [4, 5, 6];
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));

除了定义自己使用的 Symbol 值以外,ES6 还提供了 11个内置的 Symbol值,指向语言内部使用的方法。

1.11.1  迭代器介绍

迭代器(iterator)【对象中的一个属性】是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 iterator 接口,就可以完成遍历操作。
  • ES6 创造了一种新的遍历命令 for...of 循环,lterator 接口主要供 for...of 消费
  • 原生具备 iterator 接口的数据(可用 for of 遍历)

a) Array
b) Arguments
c) Set
d) Map
e) String
f) TypedArray
g) NodeList

  • 工作原理

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

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

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

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

注:需要自定义遍历数据的时候,要想到迭代器。

// 声明一个数组
const tangShengShiTu = ["唐僧", "孙悟空", "猪八戒", "沙和尚"];
// 使用 for...of 遍历数组
// for (let v of tangShengShiTu) {
//   console.log(v); // "唐僧", "孙悟空", "猪八戒", "沙和尚"
// }

let iterator = tangShengShiTu[Symbol.iterator]();
// 调用对象的next方法
console.log(iterator.next()); // {value: '唐僧', done: false}
console.log(iterator.next()); // {value: '孙悟空', done: false}
console.log(iterator.next()); // {value: '猪八戒', done: false}
console.log(iterator.next()); // {value: '沙和尚', done: false}
console.log(iterator.next()); // {value: '', done: true}

1.11.2   迭代器应用-自定义遍历数据

// 声明一个对象
const banJi = {
  name: "朗月班",
  stuList: ["xiaohong", "xiaolian", "xiaojia", "xiaoyuan"],
  [Symbol.iterator]() {
    // 索引变量
    let index = 0;
    // let _this = this;
    // return {
    //   next: function () {
    //     if (index < _this.stuList.length) {
    //       const result = { value: _this.stuList[index], done: false };
    //       // 下标自增
    //       index++;
    //       // 返回结果
    //       return result;
    //     } else {
    //       return { value: _this.stuList[index], done: true };
    //     }
    //   },
    // };
    // 使用箭头函数
    let next = () => {
      if (index < this.stuList.length) {
        const result = { value: this.stuList[index], done: false };
        // 下标自增
        index++;
        // 返回结果
        return result;
      } else {
        return { value: this.stuList[index], done: true };
      }
    };
    return { next };
  },
};

// 需求: 只能使用for of 遍历stuList,通过面向对象
// 不能使用 banJi.stuList.forEach
for (let v of banJi) {
  console.log(v); // "xiaohong", "xiaolian", "xiaojia", "xiaoyuan"
}

1.12.1   生成器函数声明与调用

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

// 生成器其实就是一个特殊的函数
// 异步编程 纯回调函数 node fs ajax mongodb
// 函数代码的分隔符
function* gen() {
  console.log("hello generator"); // hello generator
}
let iterator = gen();
iterator.next();

另一个例子

function* gen() {
  console.log(111);
  yield "光辉岁月";
  console.log(222);
  yield "蓝莲花";
  console.log(333);
  yield "像风一样自由";
  console.log(444);
}
let iterator = gen();
console.log(iterator.next()); // 111 {value: '光辉岁月', done: false}
console.log(iterator.next()); // 222 {value: '蓝莲花', done: false}
console.log(iterator.next()); // 333 {value: '像风一样自由', done: false}
console.log(iterator.next()); // 444 {value: 'undefined', done: true}
// 遍历
for (let v of gen()) {
  console.log(v);
}

遍历输出结果

1.12.2   生成器函数的参数传递

function* gen() {
  yield 111;
  yield 222;
  yield 333;
}
// 执行获取迭代器对象
let iterator = gen();
console.log(iterator.next()); // {value: 111, done: false}
console.log(iterator.next()); // {value: 222, done: false}
console.log(iterator.next()); // {value: 333, done: false}
console.log(iterator.next()); // {value: undefined, done: true}

另一个例子

function* gen(arg) {
  console.log(arg);
  let one = yield 111;
  console.log(one);
  let two = yield 222;
  console.log(two);
  let three = yield 333;
  console.log(three);
}

// 执行获取迭代器对象
let iterator = gen("AAA");
console.log(iterator.next());
// next方法可以传入实参
console.log(iterator.next("BBB")); // 第二次调用作为第一个yield的返回参数
console.log(iterator.next("CCC")); // 第三次调用作为第二个yield的返回参数
console.log(iterator.next("DDD")); // 第四次调用作为第三个yield的返回参数
console.log(iterator.next("FFF"));

输出结果

1.12.3   生成器函数实例
异步编程 文件操作 网络操作(ajax, request) 数据库操作
需求-1 1s 后控制台输出 111 2s 后控制台输出 222 3s 后控制台输出 333
  // 这种调用方式叫做回调地狱
setTimeout(() => {
  console.log(111);
  setTimeout(() => {
    console.log(222);
    setTimeout(() => {
      console.log(333);
    }, 3000);
  }, 2000);
}, 1000);

另一个例子

function one() {
  setTimeout(() => {
    console.log(111);
    iterator.next();
  }, 1000);
}
function two() {
  setTimeout(() => {
    console.log(222);
    iterator.next();
  }, 2000);
}
function three() {
  setTimeout(() => {
    console.log(333);
  }, 3000);
}
function* gen() {
  yield one();
  yield two();
  yield three();
}
// 调用生成器函数
let iterator = gen();
iterator.next();

输出结果

1.12.4   生成器函数实例-2

需求-2 模拟获取 先调用用户数据,然后调用订单数据,最后调用商品数据
function getUsers() {
  setTimeout(() => {
    let data = "用户数据";
    console.log(data);
    iterator.next();
  }, 1000);
}
function getOrders() {
  setTimeout(() => {
    let data = "订单数据";
    console.log(data);
    iterator.next();
  }, 1000);
}
function getGoods() {
  setTimeout(() => {
    let data = "商品数据";
    console.log(data);
  }, 1000);
}
function* gen() {
  yield getUsers();
  yield getOrders();
  yield getGoods();
}
// 调用生成器函数
let iterator = gen();
iterator.next();

输出结果

 需求-2,补充调用传参

function getUsers() {
  setTimeout(() => {
    let data = "用户数据1";
    iterator.next(data);
  }, 1000);
}
function getOrders() {
  setTimeout(() => {
    let data = "订单数据2";
    iterator.next(data);
  }, 1000);
}
function getGoods() {
  setTimeout(() => {
    let data = "商品数据3";
    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();

输出结果

1.13.1  Promise介绍与基本使用

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

  • Promise构造函数:Promise(excutor)
  • Promise.prototype.then 方法
  •  Promise.prototype.catch 方法
// 实例化 Promise 对象
const p = new Promise(function (resolve, reject) {
  setTimeout(() => {
    // let data = "读取用户数据";
    // resolve(data);
    let err = "读取数据失败!";
    reject(err);
  }, 1000);
});
// 调用 promise 对象的 then 方法
p.then(
  function (value) {
    console.log(value); // 读取用户数据
  },
  function (error) {
    console.error(error); // 读取数据失败!
  }
);

1.13.2  Promise封装读取文件

// 1、引入 fs 模块
const fs = require("fs");
// 2、调用方法读取文件
// fs.readFile('./resources/为学.md', (err, data) => {
//   // 如果失败,则抛出错误
//   if (err) throw err;
//   // 如果没有出错,则输出内容
//   console.log(data.toString());
// });
// 3、使用 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 (err) {
  console.log("读取失败!!")
})

输出结果

1.13.3  Promise封装AJAX请求

  • 方法-1  普通写法
// 接口地址: https://api.apiopen.top/api/getDynamic
// 1、创建对象
const xhr = new XMLHttpRequest();
// 2、初始化
xhr.open("GET", "https://api.apiopen.top/api/getDynamic");
// 3、发送
xhr.send();
// 4、绑定事件,处理响应结果
xhr.onreadystatechange = function () {
  // 判断
  if (xhr.readyState === 4) {
    // 判断响应状态码 200-299
    if (xhr.status >= 200 && xhr.status < 300) {
      console.log(xhr.response);
    } else {
      // 如果失败
      console.log(xhr.status);
    }
  }
};
  • 方法-2  Promise封装
const p = new Promise((resolve, reject) => {
  // 1、创建对象
  const xhr = new XMLHttpRequest();
  // 2、初始化
  xhr.open("GET", "https://api.apiopen.top/api/getDynamic");
  // 3、发送
  xhr.send();
  // 4、绑定事件,处理响应结果
  xhr.onreadystatechange = function () {
    // 判断
    if (xhr.readyState === 4) {
      // 判断响应状态码 200-299
      if (xhr.status >= 200 && xhr.status < 300) {
        // 表示成功
        resolve(xhr.response);
      } else {
        // 如果失败
        reject(xhr.status);
      }
    }
  };
});
// 指定回调
p.then(
  function (value) {
    console.log(value);
  },
  function (error) {
    console.log(error);
  }
);

1.13.4  Promise.prototype..then方法

// 创建 promise 对象
const p = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("获取用户数据成功!");
  }, 1000);
});
// 调用 then 方法 then方法的返回结果是 Promise 对象,对象状态由回调函数的执行结果决定
// 1、如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功,返回值为对象的成功的值
const result = p.then(
  (value) => {
    // console.log(value);
    // 1、非 promise 类型的属性
    return "I Love You";
    // 2、是promise 对象
    // return new Promise((resolve, reject) => {
      // resolve("ok");
      // reject('error');
    // });
    // 3、抛出错误
    // throw new Error("出错啦!");
    // throw '出错啦!'
  },
  (reason) => {
    console.error(reason);
  }
);
console.log(result);
// p.then(
//   (value) => {
//     console.log(value);
//   },
//   (error) => {
//     console.log(error);
//   }
// );
// 链式调用
p.then(value=>{
}).then(reason=>{
})

1.13.5  Promise实践练习-多个文件内容读取

  • 方法-1  回调地狱
fs.readFile("./resources/为学.md", (err, data1) => {
  fs.readFile("./resources/插秧诗.md", (err, data2) => {
    fs.readFile("./resources/观书有感.md", (err, data3) => {
      // let result = data1 + '\r\n' + data2 + '\r\n' + data3;
      let result = `${data1}\r\n${data2}\r\n${data3}`
      console.log(result);
    })
  })
});
  • 方法-2  使用 promise 实现
const p = new Promise((resolve, reject) => {
  fs.readFile("./resources/为学.md", (err, data) => {
    resolve(data);
  })
});
p.then(value => {
  return new Promise((resolve, reject) => {
    fs.readFile("./resources/插秧诗.md", (err, data) => {
      resolve([value, data]);
    })
  })
}).then(value => {
  return new Promise((resolve, reject) => {
    fs.readFile("./resources/观书有感.md", (err, data) => {
      // 压入
      value.push(data);
      resolve(value);
    });
  })
}).then(value => {
  console.log(value.join('\r\n'));
})
  • 方法-3  使用生成器函数
function one() {
  fs.readFile("./resources/为学.md", (err, data) => {
    iterator.next(data);
  })
}
function two() {
  fs.readFile("./resources/插秧诗.md", (err, data) => {
    iterator.next(data);
  })
}
function three() {
  fs.readFile("./resources/观书有感.md", (err, data) => {
    iterator.next(data);
  })
}
function* gen() {
  let a = yield one();
  let b = yield two();
  let c = yield three();
  let d = `${a}\r\n${b}\r\n${c}`;
  console.log(d.toString());
};
// 调用生成器函数
let iterator = gen();
iterator.next();

输出结果

1.13.6  Promise对象catch方法

const p = new Promise((resolve, reject) => {
  setTimeout(() => {
    // 设置 P 对象的状态为失败,并设置失败的值
    reject("出错啦!");
  }, 1000);
});
// p.then(value=> {
//   console.log(value);
// }, reason=>{
//   console.log(reason);
// });
p.catch((reason) => {
  console.warn(reason); // 出错啦!
});

1.14  ES6-集合介绍与API

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

  • size 返回集合的元素个数
  • add 增加一个新元素,返回当前集合
  • delete 删除元素,返回 boolean 值
  • has 检测集合中是否包含某个元素,返回 boolean 值
// 声明一个 set
let s = new Set();
console.log(s); // Set(0) {size: 0}
let s2 = new Set(["昨天", "今天", "明天", "未来", "今天"]);
console.log(s2); // Set(4) {'昨天', '今天', '明天', '未来'}
// 元素的个数
console.log(s2.size);
// 添加新的元素
s2.add("过去");
console.log(s2); // Set(5) {'昨天', '今天', '明天', '未来', '过去'}
// 删除元素
s2.delete("昨天");
console.log(s2); // Set(4) {'今天', '明天', '未来', '过去'}
// 清空
s2.clear();
console.log(s2); // Set(0) {size: 0}

1.15  ES6-集合实践

let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
  • 数组去重
let result = [...new Set(arr)];
console.log(result); // [1, 2, 3, 4, 5]
  • 交集
集合论中,设A,B是两个集合,由所有属于集合A且属于集合B的元素所组成的集合,叫做集合A与集合B的交集(intersection),记作A∩B。
let arr2 = [4, 5, 6, 5, 6];
let result = [...new Set(arr)].filter((item) => {
  let s2 = new Set(arr2); // 去重后,4 5 6
  if (s2.has(item)) {
    return true;
  } else {
    return false;
  }
});
console.log(result); // [4, 5]

交集的简写形式

let arr2 = [4, 5, 6, 5, 6];
let result = [...new Set(arr)].filter(item=>new Set(arr2).has(item));
console.log(result); // [4, 5]
  • 并集
给定两个集合A,B,把他们所有的元素合并在一起组成的集合,叫做集合A与集合B的并集,记作A∪B,读作A并B。
let arr2 = [4, 5, 6, 5, 6];
let union = [...new Set([...arr, ...arr2])];
console.log(union); // [1, 2, 3, 4, 5, 6]
  • 差集
差集是指,由所有属于A但不属于B的元素组成的集合。
let arr2 = [4, 5, 6, 5, 6];
let diff = [...new Set(arr)].filter(item=>!(new Set(arr2).has(item)));
console.log(diff); // [1, 2, 3]
1.16  ES6-Map的介绍与API

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

  • size 返回Map的元素个数
  • set 增加一个新元素,返回当前 Map
  • get 返回键名对象的键值
  • has 检测 Map 中是否包含某个元素,返回 boolean 值
  • clear 清空集合,返回undefined
// 声明 Map
let m = new Map();
// console.log(m);
// 添加元素
m.set("name", "成都大运会");
// console.log(m); // Map(1) {'name' => '成都大运会'}
m.set("change", function () {
  console.log("我可以改变世界!!");
});
let key = {
  school: "西南石油大学",
};
m.set(key, ["北京", "上海", "广州", "深圳"]);
// console.log(m);
// size
// console.log(m.size); // 3
// 删除
// m.delete("name");
// console.log(m);
// 清空
// m.clear();
// console.log(m); // Map(0) {size: 0}
// 遍历
for(let v of m) {
    console.log(v);
}

1.17.1  ES6-class介绍与初体验

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

  • class声明类
  • constructor 定义构造函数初始化
  • extends 继承父类
  • super 调用父级构造方法
  • static 定义静态方法和属性
  • 父类方法可以重写
// ES5
function Huawei(bank, price) {
  this.bank = bank;
  this.price = price;
}
// 在原型上添加方法
Huawei.prototype.call = function () {
  console.log("我可以打电话哦!");
};
let hW = new Huawei("3999", "华为荣耀");
hW.call();
console.log(hW);
// ES6
class XiaoMi {
  constructor(bank, price) {
    this.bank = bank;
    this.price = price;
  }
  // 方法必须使用该语法,不能使用 ES5 的对象完整形式
  call() {
    console.log("我为发烧而生");
  }
}
let xM = new XiaoMi("699", "红米");
xM.call();
console.log(xM);

输出结果

1.17.2  ES6-class静态成员

// 构造函数也是一个对象
function Phone() {}
Phone.name = "手机";
Phone.change = function () {
  console.log("我可以改变世界!");
};
Phone.prototype.size = "5.5inch";
// 实例对象是实例对象,函数对象是函数对象。
let tianYu = new Phone();
console.log(tianYu.name); // undefined
// tianYu.change(); // error tianYu.change is not a function
console.log(tianYu.size); // 5.5inch
class Computer {
  // 静态属性
  static name = "戴尔";
  static change() {
    console.log("我可以改变世界!");
  }
}
let dianNao = new Computer();
console.log(dianNao.name); // undefined
// 静态方法是属于类,不属于实例方法
console.log(Computer.name); // 戴尔
1.17.3  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.price = price;
}
// 设置子构造函数的原型
SmartPhone.prototype = new Phone();
// 校正一下,你不这样做也行
// SmartPhone.prototype.constructor = SmartPhone;
// 声明子类的方法
SmartPhone.prototype.photo = function () {
  console.log("我可以拍照");
};
SmartPhone.prototype.playGame = function () {
  console.log("我可以打游戏");
};
const chuiZi = new SmartPhone("锤子", 2999, "黑色", "5.5inch");
console.log(chuiZi);
chuiZi.call();
chuiZi.photo();
chuiZi.playGame();

 输出结果

1.17.4  ES6-class的类继承

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); // Phone.call(this, brand, price);
    this.color = color;
    this.size = size;
  }
  photo() {
    console.log("我能拍照!");
  }
  playGame() {
    console.log("我能玩游戏!");
  }
}
let xiaoMi = new SmartPhone("小米", 699, "黑色", "5.5inch");
console.log(xiaoMi);
xiaoMi.call();
xiaoMi.photo();
xiaoMi.playGame();

 输出结果

1.17.4  ES6-子类对父类方法的重写

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); // Phone.call(this, brand, price);
    this.color = color;
    this.size = size;
  }
  photo() {
    console.log("我能拍照!");
  }
  playGame() {
    console.log("我能玩游戏!");
  }
  // ES6-子类对父类方法的重写
  call() {
    console.log("我可以视频通话哦!");
  }
}
let xiaoMi = new SmartPhone("小米", 699, "黑色", "5.5inch");
console.log(xiaoMi);
xiaoMi.call();
xiaoMi.photo();
xiaoMi.playGame();

 输出结果

1.18  ES6的数值扩展

  • Number.EPSILON 是 JavaScript 表示的最小精度
 EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16
function equal(a, b) {
  if (Math.abs(a - b) < Number.EPSILON) {
    return true;
  } else {
    return false;
  }
}
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false
console.log(equal(0.1 + 0.2, 0.3)); // true
  • 二进制和八进制
let b = 0b1010;
console.log(b); // 10
let o = 0o777;
console.log(o); // 511
let d = 100;
console.log(d); // 100
let x = 0xff;
console.log(x); // 255
  • Number.isNaN 检测一个数值是否为 NaN
console.log(Number.isNaN(123)); // false
  • Number.parseInt Number.parseFloat字符串转整数
console.log(Number.parseInt("511111fuck")); // 511111
console.log(Number.parseFloat("3.1415926疯狂")); // 3.1415926
  • Number.isInteger() 判断一个数是否为整数
console.log(Number.isInteger(5)); // true
console.log(Number.isInteger(2.5)); // false
  • Math.trunc 将数字的小数部分抹掉
console.log(Math.trunc(3.5)); // 3
  • Math.sign 判断一个数到底为正数 负数 还是零
console.log(Math.sign(100)); // 1
console.log(Math.sign(0)); // 0
console.log(Math.sign(-20000)); // -1

1.19  ES6的对象方法扩展

  • Object.is 判断两个值是否完全相等
console.log(Object.is(120, 120)); // true ===
console.log(Object.is(NaN, NaN)); // true
console.log(NaN === NaN); // false
  • Object.assign 对象的合并
const obj1 = {
  host: "localhost",
  port: 3306,
  username: "admin",
  password: "admin",
};
const obj2 = {
  host: "127.0.0.1",
  port: 8080,
  username: "root",
  password: "root",
  isLogin: false,
};
console.log(Object.assign(obj1, obj2)); // {host: '127.0.0.1', port: 8080, username: 'root', password: 'root', isLogin: false}
  • Object.setPrototypeOf 设置原型对象  Object.getPrototypeof
const school = {
  name: "研究院",
};
const cities = {
  xiaoqu: ["北京", "上海", "广州"],
};
Object.setPrototypeOf(school, cities);
console.log(Object.getPrototypeOf(school));
console.log(school);

输出结果

1.20.1  ES6-模块化介绍、优势以及产品

  • 模块化
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
  • 模块化的好处
模块化的优势有以下几点:
1)  防止命名冲突
2)  代码复用
3)  高维护性
  • 模块化规范产品
ES6之前的模块化规范有:
1)  CommonJS => NodeJS、Browserify
2)  AMD => requireJS
3)  CMD => seaJS
  • ES6 模块化语法
模块功能主要由两个命令构成:export 和import。
1) export 命令用于规定模块的对外接口
2) import 命令用于输入其他模块提供的功能
 
1.20.2  ES6-浏览器使用ES6模块化引入模块
html代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ES6-浏览器使用ES6模块化引入模块</title>
  </head>
  <body>
    <script type="module">
      // 引入 m1.js 模块内容
      import * as m1 from "./src/js/m1.js";
      console.log(m1);
      m1.study();
    </script>
  </body>
</html>

js代码-m1.js

// 分别暴露
export let school = "西南石油大学";
export function study() {
    console.log("我可以学习到新的技能!!")
}

1.20.3  ES6模块暴露数据语法汇总

html代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ES6模块暴露数据语法汇总</title>
  </head>
  <body>
    <script type="module">
      // 引入 m1.js 模块内容
      import * as m1 from "./src/js/m1.js";
      console.log(m1);
      m1.study();
      // 引入 m2.js 模块内容
      import * as m2 from "./src/js/m2.js";
      console.log(m2);
      m2.findJob();
      // 引入 m3.js 模块内容
      import * as m3 from "./src/js/m3.js";
      console.log(m3);
      m3.default.change();
    </script>
  </body>
</html>

js代码-m2.js

// 统一暴露
let school = "西南石油大学";
function findJob() {
    console.log("我一定能行!");
}
export { school, findJob };

js代码-m3.js

// 默认暴露
export default {
    school: "西南石油大学",
    change: function () {
        console.log("我可以改变自己!");
    }
}

1.20.4  ES6引入模块数据语法汇总

html代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ES6引入模块数据语法汇总</title>
  </head>
  <body>
    <script type="module">
      // 1、通用的导入方法
      // 引入 m1.js 模块内容
      import * as m1 from "./src/js/m1.js";
      // console.log(m1);
      // m1.study();
      // 引入 m2.js 模块内容
      import * as m2 from "./src/js/m2.js";
      // console.log(m2);
      // m2.study();
      // 引入 m3.js 模块内容
      // import * as m3 from "./src/js/m3.js";
      // console.log(m3);
      // m3.default.study();

      // 2、结构赋值形式
      // import { school, study } from "./src/js/m1.js";
      // console.log(school);
      // study();
      // 使用别名
      // import { school as xueXiao, study as learn } from "./src/js/m2.js";
      // console.log(xueXiao);
      // learn();
      // import { default as m3 } from "./src/js/m3.js";
      // console.log(m3);

      // 3、简便形式 针对默认暴露
      import m3 from "./src/js/m3.js";
      console.log(m3);
    </script>
  </body>
</html>

1.20.5  ES6-浏览器使用ES6模块化方式二

html代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ES6-浏览器使用ES6模块化方式二</title>
  </head>
  <body>
    <!-- 模块化方式一 -->
    <script type="module">
      // 1、通用的导入方法
      // 引入 m1.js 模块内容
      // import * as m1 from "./src/js/m1.js";
      // console.log(m1);
      // m1.study();
      // 引入 m2.js 模块内容
      // import * as m2 from "./src/js/m2.js";
      // console.log(m2);
      // m2.study();
      // 引入 m3.js 模块内容
      // import * as m3 from "./src/js/m3.js";
      // console.log(m3);
      // m3.default.study();
      // 2、结构赋值形式
      // import { school, study } from "./src/js/m1.js";
      // console.log(school);
      // study();
      // 使用别名
      // import { school as xueXiao, study as learn } from "./src/js/m2.js";
      // console.log(xueXiao);
      // learn();
      // import { default as m3 } from "./src/js/m3.js";
      // console.log(m3);
      // 3、简便形式 针对默认暴露
      // import m3 from "./src/js/m3.js";
      // console.log(m3);
    </script>
    <!-- 模块化方式二 -->
    <script src="./src/js/app.js" type="module"></script>
  </body>
</html>

1.20.6  ES6-babel对ES6模块化代码转换

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ES6-babel对ES6模块化代码转换</title>
  </head>
  <body>
    <!-- 
      步骤:
      0、先做一个初始化  npm init --yes
      1、安装工具 npm i babel-cli babel-preset-env browserify(webpack) -D   
      2、编译 npx babel src/js -d dist/js --presets=babel-preset-env
      3、打包 npx browserify dist/js/app.js -o dist/bundle.js
     -->
    <script src="./dist/bundle.js" type="module"></script>
  </body>
</html>

1.20.7  ES6模块化引入NPM包

需求-修改页面的背景颜色为粉色
步骤:

1)安装jquery npm i jquery

2)html代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ES6模块化引入NPM包</title>
  </head>
  <body>
    <script src="./dist/bundle.js" type="module"></script>
  </body>
</html>

3)js代码-app.js

import $ from 'jquery';  // const $ = require("jquery");
$("body").css("background", "pink");

2.  ES7

2.1  ES7新特性

  • Arrayprototype.includes
Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值
const mingZhu = ["西游记", "红楼梦", "三国演义", "水浒传"];
console.log(mingZhu.includes("西游记")); // true
console.log(mingZhu.includes("石头记")); // false
  • 指数操作符
在ES7中引入指数运算符[**],用来实现幂运算,功能与Math.pow 结果相同
console.log(2 ** 10); // 1024
console.log(Math.pow(2, 10)); // 1024

3.  ES8

3.1  ES8-async函数

  • async和await

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

  • async函数

1)async函数的返回值为 promise 对象,
2)promise对象的结果由 async函数执行的返回值决定

// async 函数
async function fn() {
  // 返回一个字符串
  // return "好炎热";
  // 返回的结果不是一个 Promise 类型的对象,返回的结果就是成功 Promise 对象
  // return;
  // 抛出错误,返回的结果是一个失败的 Promise
  // throw new Error("出错啦!");
  // 返回的结果如果是一个 Promise 对象
  return new Promise((resolve, reject) => {
    // resolve("读取数据成功!");
    reject("读取数据失败!");
  });
}
const result = fn();
// console.log(result);
// 调用 then 方法
result.then(value => {
    console.log(value);
  },reason => {
    console.warn(reason);
  }
);

3.2  ES8-await表达式

  • await 表达式

1)await 必须写在async函数中
2)await 右侧的表达式一般为 promise 对象
3)await 返回的是 promise 成功的值
4)await 的 promise 失败了,就会抛出异常,需要通过 try...catch 捕获处理

// 创建 Promise 对象
let p = new Promise((resolve, reject) => {
  // resolve("请求成功!");
  reject("请求失败!");
});
// await 要放在 async 函数中.
async function main() {
  try {
    let result = await p;
    console.log(result);
  } catch (e) {
    console.error(e);
  }
}
// 调用函数
main();

3.3  ES8-async与await结合读取文件内容

// 引入fs
const fs = require("fs");
// 读取为学
function readWeiXue() {
  return new Promise((resolve, reject) => {
    fs.readFile("./resources/为学.md", (err, data) => {
      // 如果失败
      if (err) reject(err);
      // 如果成功
      resolve(data);
    })
  })
}
// 读取插秧诗
function readChaYangShi() {
  return new Promise((resolve, reject) => {
    fs.readFile("./resources/插秧诗.md", (err, data) => {
      // 如果失败
      if (err) reject(err);
      // 如果成功
      resolve(data);
    })
  })
}
// 读取观书有感
function readGuanShu() {
  return new Promise((resolve, reject) => {
    fs.readFile("./resources/观书有感.md", (err, data) => {
      // 如果失败
      if (err) reject(err);
      // 如果成功
      resolve(data);
    })
  })
}
//声明一个 async 函数
async function main() {
  // 获取为学内容
  let weiXue = await readWeiXue();
  // 获取插秧诗内容
  let chaYang = await readChaYangShi();
  // 获取观书有感
  let guanShu = await readGuanShu();
  console.log(weiXue.toString());
  console.log(chaYang.toString());
  console.log(guanShu.toString());
}
main();

3.4  ES8-async与await结合发送AJAX请求

// 发送 AJAX 请求,返回的结果是 Promise 对象
function sendAJAX(url) {
  return new Promise((resolve, reject) => {
    // 1、创建对象
    const x = new XMLHttpRequest();
    // 2、初始化
    x.open("GET", url);
    // 3、发送
    x.send();
    // 4、事件绑定
    x.onreadystatechange = function () {
      if (x.readyState === 4) {
        if (x.status >= 200 && x.status < 300) {
          // 请求成功
          resolve(x.response);
        } else {
          // 请求失败
          reject(x.status);
        }
      }
    };
  });
}
// Promise then 方法的测试
// sendAJAX("https://api.apiopen.top/api/getDynamic").then(value=>{
//   console.log(value);
// },reason=>{
// });
// async 与 await 测试
async function main() {
  // 发送 AJAX 请求
  let result = await sendAJAX("https://api.apiopen.top/api/getDynamic");
  // console.log(result);
  let tianQi = await sendAJAX(
    "https://www.tianqiapi.com/api/?version=v1&city=%E5%8C%97%E4%BA%AC&appid=23941491&appsecret=TXoD5e8P"
  );
  console.log(tianQi);
}
main();

3.5  ES8对象方法扩展

  • Obiect.values 和 Obiect.entries
1)Obiect.values()方法返回一个给定对象的所有可枚举属性值的数组
2)Obiect.entries()方法返回一个给定对象自身可遍历属性 [key,value] 的数组
// 声明对象
const school = {
  name: "西南石油大学",
  xiaoqu: ["新都", "南充"],
  major: ["计算机科学与技术", "软件工程", "人工智能"],
};
获取对象所有的键
console.log(Object.keys(school));
输出结果

获取对象所有的值
console.log(Object.values(school));
输出结果

 entries

console.log(Object.entries(school));
输出结果

  •  Object.getOwnPropertyDescriptors
该方法返回指定对象所有自身属性的描述对象
console.log(Object.getOwnPropertyDescriptors(school));
输出结果

 使用Object.create()创建对象

const obj = Object.create(null, {
  name: {
    // 设置值
    value: "哈哈",
    // 属性特征
    writable: true,
    configurable: true,
    enumerable: true,
  },
});
console.log(obj); // {name: '哈哈'}

4.  ES9

4.1  ES9扩展运算符与rest参数

Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符。
rest 参数
function connect({ host, port, ...user }) {
  console.log(host); // 127.0.0.1
  console.log(port); // 3306
  console.log(user); // {username: 'root', password: 'root', type: 'master'}
}
connect({
  host: "127.0.0.1",
  port: 3306,
  username: "root",
  password: "root",
  type: "master",
});
对象合并
const skillOne = {
  a: "html5",
  k: "其他",
};
console.log({ ...skillOne }); // {a: 'html5', k: '其他'}
// console.log({ ...skillOne }['a']); // html5
const skillTwo = {
  b: "css3",
};
const skillThree = {
  c: "vue3",
};
const skillFour = {
  d: "react",
};
const skill = { ...skillOne, ...skillTwo, ...skillThree, ...skillFour };
console.log(skill); // {a: 'html5', k: '其他', b: 'css3', c: 'vue3', d: 'react'}
console.log(skill["d"]); // react

4.2  ES9正则扩展-命名捕获分组

声明一个字符串
let str = '<a href="https://www.baidu.com">百度</a>';
// 提取 url 与 『标签文本』
const reg = /<a href="(.*)">(.*)<\/a>/;
// 执行
const result = reg.exec(str);
console.log(result);
console.log(result[1]); // https://www.baidu.com
console.log(result[2]); // 百度

输出结果

 分组命名

const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result = reg.exec(str);
console.log(result);
console.log(result.groups.url); // https://www.baidu.com
console.log(result.groups.text); // 百度

输出结果

4.3  ES9正则扩展-反向断言

// 声明字符串
let str = 'JS5211314你知道么555啦啦啦';
1)正向断言
const reg = /\d+(?=啦)/;
const result = reg.exec(str);
console.log(result);
2)反向断言
const reg = /(?<=么)\d+/;
const result = reg.exec(str);
console.log(result);

输出结果

4.4  ES9正则扩展-dotAll模式

dot . 元字符 除换行符以外的任意单个字符
需求-提取html标签中的文本内容
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>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/;
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;
// 执行匹配
let result;
let data = [];
while ((result = reg.exec(str))) {
  data.push({ title: result[1], time: result[2] });
}
// 输出结果
console.log(data);

输出结果

5.  ES10

5.1  ES10-对象扩展方法Object.fromEntries

// 二维数组转换成对象
const result = Object.fromEntries([
  ["name", "西南石油大学"],
  ["zhuanYe", "计算机科学与技术, 软件工程, 人工智能"],
]);
console.log(result); // {name: '西南石油大学', zhuanYe: '计算机科学与技术, 软件工程, 人工智能'}
// Map
const m = new Map();
m.set("name", "电子科大");
m.set("zhuanYe", "大数据");
const result = Object.fromEntries(m);
console.log(result); // {name: '电子科大', zhuanYe: '大数据'}
// Object.entries ES8 对象转二维数组
const arr = Object.entries({
  name: "红石榴21",
});
console.log(arr); // [["name","红石榴21"]]

5.2  ES10-字符串方法扩展-trimStart-trimEnd

  • trim
let str = "  Hello World  ";
console.log(str);
console.log(str.trimStart());
console.log(str.trimEnd());

输出结果

5.3  ES10-数组方法扩展-flat与flatMap

  • flat 平铺
将多维数组转化为低位数组
const arr = [1, 2, 3, 4, [5, 6]];
console.log(arr.flat()); // [1, 2, 3, 4, 5, 6]
const arr2 = [1, 2, 3, [5, 6, [7, 8, 9]]];
// 参数为深度 是一个数字
console.log(arr2.flat(2)); // [1, 2, 3, 5, 6, 7, 8, 9]
  • flatMap
const arr3 = [1, 2, 3, 4];
const result = arr3.flatMap((item) => [item * 10]);
console.log(result); // [10, 20, 30, 40]

5.4  ES10-Symbol.prototype.description

// 创建Symbol
let s = Symbol("西南石油大学");
console.log(s.description); // 西南石油大学

6.  ES11

6.1  ES11-私有属性
class Person {
// 公有属性
name;
// 私有属性
#age;
#weight;
// 构造方法
constructor(name, age, weight) {
    this.name = name;
    this.#age = age;
    this.#weight = weight;
}
intro() {
    console.log(this.name); // 尕车
    console.log(this.#age); // 18
    console.log(this.#weight); // 45kg
}
}
// 实例化
const girl = new Person("尕车", 18, "45kg");
console.log(girl.name);
//   console.log(girl.#age); // error
//   console.log(girl.#weight); // error
girl.intro();

6.2  ES11-Promise.allSettled方法

// 声明两个Promise对象
const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    // resolve("商品数量-1");
    reject("出错啦!");
  }, 1000);
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("商品数量-2");
  }, 1000);
});
// 调用allSettled 方法
// 就算有一个失败,也会都会返回
const result = Promise.allSettled([p1, p2]);
console.log(result);
// 调用all 方法
// 两个都成功,才会返回结果
const res = Promise.all([p1, p2]);
console.log(res);
调用allSettled 方法,输出结果

 调用all 方法,输出结果

 6.3  ES11-String.prototype.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>/gs;
// 调用方法
const result = str.matchAll(reg);
// for(let v of result){
//   console.log(v);
// }
// console.log(result);
const arr = [...result];
console.log(arr);

 6.4  ES11-可选链操作符

?.
function main(config) {
  // const dbHost = config && config.db && config.db.host;
  const dbHost = config?.db?.host;
  console.log(dbHost);
}
main({
  db: {
    host: "127.0.0.1",
    username: "root"
  },
  cache: {
    host: "127.0.0.2",
    username: "admin"
  },
});

6.5  ES11-动态import

html页面

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ES11-动态import</title>
  </head>
  <body>
    <button id="btn">点击</button>
    <script src="./js/app.js" type="module"></script>
  </body>
</html>

app.js

// import * as  m1 from "./hello.js"; 静态 import
// 获取元素
const btn = document.getElementById("btn");
btn.onclick = function () {
    // 动态 import
    import('./hello.js').then(module => {
        module.hello();
    })
}

hello.js

export function hello() {
    alert("Hello");
}

6.6  ES11-BigInt类型

// 大整形
// let n = 521n;
// console.log(n, typeof n); // 521n 'bigint'
// 函数
// let n = 123;
// console.log(BigInt(n)); // 123n
// console.log(BigInt(1.2)); // error
// 大数值运算
let max = Number.MAX_SAFE_INTEGER;
console.log(max); // 9007199254740991
console.log(max + 1); // 9007199254740992
console.log(max + 2); // 9007199254740992
console.log(BigInt(max)); // 9007199254740991n
console.log(BigInt(max) + BigInt(1)); // 9007199254740992n
console.log(BigInt(max) + BigInt(2)); // 9007199254740993n

6.7  ES11-绝对全局对象globalThis

在html页面中

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ES11-绝对全局对象globalThis</title>
  </head>
  <body>
    <script>
      console.log(globalThis);
    </script>
  </body>
</html>

输出结果

在node运行中

console.log(globalThis);
输出结果

鉴定完毕,欢迎友们一起交流学习!

posted @ 2023-09-10 17:34  红石榴21  阅读(143)  评论(0编辑  收藏  举报