ES6~ES11学习笔记

一、let和const

1.1 let

1.1.1 声明变量

let a;
let b, c, d;
let e = 1;
let f = 10, g = 'hello', h = [];

1.1.2 变量不能重复声明

let star = "罗志祥";
let star = "小猪";

报错

在这里插入图片描述

var可以重复声明变量

var star = "罗志祥";
var star = "小猪";

1.1.3 块级作用域

  • 全局

  • 函数

  • eval(严格模式)

{
    let girl = "周扬青";
}
console.log(girl);

报错

在这里插入图片描述

var 没有块级作用域

{
    var girl = "周扬青";
}
console.log(girl);

在这里插入图片描述

1.1.4 不存在变量提升

console.log(song);
let song = "两只老虎";

报错

在这里插入图片描述

var 存在变量提升

console.log(song);
var song = "两只老虎";
// 相当于 
// var song;  
// console.log(song);

在这里插入图片描述

1.1.5 不影响作用域链

{
      let school = "尚硅谷";
      function fn() {
        console.log(school);
      }
      fn();
}

在这里插入图片描述

1.2 const

1.2.1 定义常量(常量:值不能修改)

const PI = 3.14;
console.log(PI);

在这里插入图片描述

1.2.2 必须赋初始值

const PI;

报错

在这里插入图片描述

1.2.3 一般常量使用大写(潜规则)

const PI = 3.14;
// 小写也不会报错
const pi = 3.14;

1.2.4 常量的值不能修改

const PI = 3.14;
PI = 3.1415926;

报错

在这里插入图片描述

1.2.5 块级作用域

{
    const PI = 3.14;
}
console.log(PI);

报错

在这里插入图片描述

1.2.6 可对数组和对象的元素修改

const arr = ['a', 'b', 'c'];
arr.push("d");
console.log(arr);   //arr指向的地址没发生改变

在这里插入图片描述

const obj = {
      name: "小明",
      age: 18
}
obj.name = "小红";
console.log(obj);

在这里插入图片描述

二、变量的结构赋值

ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。

2.1 数组的解构

const F4 = ["小沈阳", "刘能", "赵四", "宋小宝"];
let [xiao, liu, zhao, song] = F4;
console.log(xiao);
console.log(liu);
console.log(zhao);
console.log(song);

在这里插入图片描述

2.2 对象的解构

const zhao = {
      name: "赵本山",
      age: 60,
      xiaopin: function () {
        console.log("演小品");
      }
}

let { name, age, xiaopin } = zhao;
console.log(name);
console.log(age);
console.log(xiaopin);
xiaopin();

在这里插入图片描述

按需求解构

let { xiaopin } = zhao;
xiaopin();

在这里插入图片描述

三、模板字符串

ES6 引入新的声明字符串的方式 ````;ES5:单引号(’ ')、双引号(" ")。

3.1 声明

let str = `我是字符串`;
console.log(str, typeof str);

在这里插入图片描述

3.2 特性

3.2.1 内容中可以直接出现换行符

let str = `<ul>
                  <li>javascript</li>
                  <li>java</li>
                  <li>go</li>
            </ul>`;

不会报错

单引号或双引号换行要使用+拼接,否则换行就会报错

let str = '<ul>
                  <li>javascript</li>
                  <li>java</li>
                  <li>go</li>
            </ul>';

报错

 let str = '<ul>' +
                  '<li>javascript</li>' +
                  '<li>java</li>' +
                  '<li>go</li>' +
            '</ul>';

+ 连接不会报错

3.2.2 变量拼接

let star = "刘亦菲";
let love = `${star}是明星`;
console.log(love);

在这里插入图片描述

四、对象的简化写法

ES6 允许在大括号里边,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

let name = "旺财";
    let food = function () {
      console.log("我喜欢吃骨头");
    }

    const dog = {
      // 之前的写法
      // name: name,
      // food: food,
      // run: function () {
      //   console.log("我跑得快");
      // }
      // ES6 的写法
      name,
      food,
      run() {
        console.log("我跑得快");
      }
}

console.log(dog);

五、箭头函数

ES6 允许使用 箭头 (=>) 定义函数。

    // 普通函数
    // let fn = function (a, b) {
    //   return a + b;
    // }
    // let result = fn(10, 20);
    // console.log(result);

    // 箭头函数
    let fn = (a, b) => {
      return a + b;
    }
    let result = fn(10, 20);
    console.log(result);

在这里插入图片描述

5.1 this 静态特点

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

    function getName1() {
      console.log(this.name);
    }

    let getName2 = () => {
      console.log(this.name);
    }

    // 设置 window 对象的 name 属性
    window.name = "Hello";

    // 直接调用
    getName1();
    getName2();

在这里插入图片描述

    function getName1() {
      console.log(this.name);
    }

    let getName2 = () => {
      console.log(this.name);
    }

    // 设置 window 对象的 name 属性
    window.name = "Hello";

    const obj = {
      name: "你好"
    }

    // call 方法调用
    getName1.call(obj);
    getName2.call(obj);

在这里插入图片描述

5.2 不能作为构造实例化对象

    let Person = (name, age) => {
      this.name = name;
      this.age = age;
    }
    let me = new Person("张三", 20);
    console.log(me);

报错

在这里插入图片描述

5.3 不能使用 arguments 变量

    let fn = () => {
      console.log(arguments);
    }
    fn(1, 2, 3);

在这里插入图片描述

5.4 箭头函数的简写

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

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

在这里插入图片描述

5.4.2 省略花括号,当代码体只有一条语句时,此时return也必须省略

    let pow = x => x * x;
    console.log(pow(9));

在这里插入图片描述

5.5 应用场景

箭头函数适合与 this 无关的回调。定时器、数组的方法回调等。

箭头函数不适合与 this 有关的回调。事件回调,对象的方法等。

六、函数参数的默认值

ES6 允许给函数参数赋初始值。

形参初始值,具有默认值的参数,一般位置要靠后

    function fun(a, b, c) {
      return a + b + c;
    }
    let result = fun(1, 2);
    console.log(result);lt);

在这里插入图片描述

    function fun(a, b, c = 5) {
      return a + b + c;
    }
    let result = fun(1, 2);
    console.log(result);

在这里插入图片描述

与解构赋值结合使用

    function connect({ host = "127.0.0.1", port, username, password }) {
      console.log(host);
      console.log(port);
      console.log(username);
      console.log(password);
    }
    connect({
      host: "localhost",
      port: 8080,
      username: "root",
      password: "root"
    })

在这里插入图片描述

七、rest 参数

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

ES5 获取实参的方式

    // ES5 获取实参的方式
    function date() {
      console.log(arguments);
    }
    date("hello", "world", "!");     //获取到的是对象

在这里插入图片描述

ES6 获取实参的方式

    function date(...args) {
      console.log(args);
    }
    date("hello", "world", "!");   //获取到的是数组,可以使用数组的API方法,如filter,some,every,map等

在这里插入图片描述

rest 参数必须要放到参数最后

    function fun(a, b, ...args) {
      console.log(a);
      console.log(b);
      console.log(...args);
    }

在这里插入图片描述

七、扩展运算符

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

7.1 使用

    const tfboys = ["易烊千玺", "王源", "王俊凯"];

    function chunwan() {
      console.log(arguments);
    }

    chunwan(tfboys);

一个参数

在这里插入图片描述

chunwan(...tfboys);

三个参数

在这里插入图片描述

7.2 应用

7.2.1 数组的合并

    const arr1 = ['a', 'b', 'c'];
    const arr2 = ['d', 'e', 'f'];
    // ES5 的写法
    // const arr = arr1.concat(arr2);
    // console.log(arr); 

    // ES6 
    const arr = [...arr1, ...arr2];
    console.log(arr);

在这里插入图片描述

7.2.2 数组的克隆

    const arr1 = ['a', 'b', 'c'];
    const arr2 = [...arr1];
    console.log(arr2);

在这里插入图片描述

7.2.3 将伪数组转为真正的数组

    const divs = document.querySelectorAll("div");
    console.log(divs);  //obj
    const divArr = [...divs];
    console.log(divArr); //转化为数组

在这里插入图片描述

八、Symbol

8.1 Symbol基本使用

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。

Symbol 特点

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

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

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

    // 创建 Symbol
    let s1 = Symbol();
    console.log(s1, typeof s1);

    let s2 = Symbol("张三");
    let s3 = Symbol("张三");
    console.log(s2);
    console.log(s2 === s3);   //false

    let s4 = Symbol.for("李四");
    let s5 = Symbol.for("李四");
    console.log(s4 === s5);   //true

    // 不能与其他数据进行运算(以下是错误写法)
    // let result1 = s + 100;
    // let result2 = s > 100;
    // let result3 = s + '100';
    // let result4 = s + s;

在这里插入图片描述

js的数据类型(7种)

USONB:you are so niubility(你很牛逼)

U:undefined

S:string symbol

O:object

N:null number

B:boolean

8.2 对象添加 Symbol 类型的属性

    let game = {
      name: "俄罗斯方块",
      up: function () {
        console.log("向上");
      },
      down: function () {
        console.log("向下");
      }
    }

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

    game[methods.up] = function () {
      console.log("我可以向上");
    };

    game[methods.down] = function () {
      console.log("我可以向下");
    }

    console.log(game);

    let youxi = {
      name: "王者荣耀",
      [Symbol('ptgj')]: function () {
        console.log("普通攻击");
      },
      [Symbol('fdz')]: function () {
        console.log("放大招");
      }
    }

    console.log(youxi);

在这里插入图片描述

8.3 Symbol 的内置属性

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

属性说明
Symbol.hasInstance当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法。
Symbol.isConcatSpreadable对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于 Array.prototype.concat()时,是否可以展开。
Symbol.unscopables该对象指定了使用 with 关键字时,哪些属性会被 with 环境排除。
Symbol.match当执行 str.match(myObject) 时,如果该属性存在,会调用它,返回改方法的返回值。
Symbol.replace当对象被 str.replace(myObject) 方法调用时,会返回改方法的返回值。
Symbol.search当改对象被 str.search(myObject) 方法调用时,会返回该方法的返回值。
Symbol.split当该对象被 str.split(myObject) 方法调用时,会返回改方法的返回值。
Symbol.iterator对象进行 for…of 循环时,会调用 Symbol.iterator 方法,返回该对象额默认遍历器。
Symbol.toPrimitive该对象被转为原始类型的值时,会调用这个方法,返回改对象对应的原始类型值。
Symbol.toStringTag在该对象上面调用 toString 方法时,返回该方法的返回值。
Symbol.species创建衍生对象时,会使用该属性。

九、迭代器

迭代器(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 属性的对象

    const arr = ['唐僧', '孙悟空', '猪八戒', '沙悟净'];

    for (let v of arr) {
      console.log(v);
    }

    console.log("=========");

    for (let v in arr) {
      console.log(v);
    }

    console.log(arr);

    let iterator = arr[Symbol.iterator]();

    // 调用对象的 next 方法
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());

在这里插入图片描述

迭代器的应用

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

    const banji = {
      name: "一班",
      stus: [
        "小明",
        "小强",
        "小花",
        "小红"
      ],
      [Symbol.iterator]() {
        // 索引变量
        let index = 0;
        let _this = this;
        return {
          next: function () {
            if (index < _this.stus.length) {
              const result = { value: _this.stus[index], done: false };
              // 下标自增
              index++;
              // 返回结果
              return result;
            } else {
              return { value: undefined, done: true };
            }

          }
        }
      }
    }

    for (let v of banji) {
      console.log(v);
    }

在这里插入图片描述

十、生成器

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

10.1 生成器函数声明与调用

    function* gen() {
      console.log("hello generoter");
      // yield 可理解为函数代码的分隔符
      yield '一直没有耳朵';
      yield '一只没有尾巴';
      yield '真奇怪';
    }

    let iterator = gen();

    console.log(iterator);

    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());

    // 遍历
    for (let v of gen()) {
      console.log(v);
    }

在这里插入图片描述

10.2 生成函数的参数传递

    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"));
    console.log(iterator.next("CCC"));
    console.log(iterator.next("DDD"));
    console.log(iterator.next("EEE"));

在这里插入图片描述

10.3 案例

    function getUsers() {
      setTimeout(() => {
        let data = '用户数据';
        iterator.next(data);
      }, 1000)
    }

    function getOrders() {
      setTimeout(() => {
        let data = '订单数据';
        iterator.next(data);
      }, 1000)
    }

    function getGoods() {
      setTimeout(() => {
        let data = '商品数据';
        iterator.next(data);
      }, 1000)
    }

    function* gen() {
      let users = yield getUsers();
      console.log(users);
      let orders = yield getOrders();
      console.log(orders);
      let goods = yield getGoods();
      console.log(goods);
    }

    // 调用生成器函数
    let iterator = gen();
    iterator.next();

在这里插入图片描述

十一、Promise

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

  1. Promise 构造函数:Promise(excutor){}

  2. Promise.prototype.then 方法

  3. Promise.prototype.catch 方法

11.1 基本使用

    const p = new Promise(function (resolve, reject) {
      setTimeout(function () {
        let data = '数据库中的用户数据'
        resolve(data);

        // let err = '数据读取失败';
        // reject(err);
      }, 1000)
    });

    // 调用 Promise 对象的 then 方法
    p.then(function (value) {
      console.log(value);
    }, function (reason) {
      console.error(reason);
    })

在这里插入图片描述

    const p = new Promise(function (resolve, reject) {
      setTimeout(function () {
        // let data = '数据库中的用户数据'
        // resolve(data);

        let err = '数据读取失败';
        reject(err);
      }, 1000)
    });

    // 调用 Promise 对象的 then 方法
    p.then(function (value) {
      console.log(value);
    }, function (reason) {
      console.error(reason);
    })

在这里插入图片描述

11.2 封装读取文件

// 引入 fs 模块
const fs = require('fs');

// 调用方法读取文件
// fs.readFile('./resources/hello1.txt', (err, data) => {
//   // 失败
//   if (err) throw err;
//   // 成功
//   console.log(data.toString());
// });

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

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

在这里插入图片描述

11.3 Promise 封装 AJAX 请求

    // 接口地址:https://api.apiopen.top/api/sentences  get

    // // 1. 创建对象
    // const xhr = new XMLHttpRequest();
    // // 2. 初始化
    // xhr.open("GET", "https://api.apiopen.top/api/sentences");
    // // 3. 发送
    // xhr.send();
    // // 4. 绑定事件,处理响应结果
    // xhr.onreadystatechange = function () {
    //   // 判断
    //   if (xhr.readyState === 4) {
    //     // 判断响应状态码 200-299
    //     if (xhr.status >= 200 && xhr.status <= 299) {
    //       // 表示成功
    //       console.log(xhr.response);
    //     } else {
    //       console.error(xhr.status);
    //     }
    //   }
    // }

    // 封装
    const p = new Promise((resolve, reject) => {
      // 1. 创建对象
      const xhr = new XMLHttpRequest();
      // 2. 初始化
      xhr.open("GET", "https://api.apiopen.top/api/sentences");
      // 3. 发送
      xhr.send();
      // 4. 绑定事件,处理响应结果
      xhr.onreadystatechange = function () {
        // 判断
        if (xhr.readyState === 4) {
          // 判断响应状态码 200-299
          if (xhr.status >= 200 && xhr.status <= 299) {
            // 表示成功
            resolve(xhr.response);
          } else {
            reject(xhr.status);
          }
        }
      }
    })

    // 指定回调
    p.then(function (value) {
      console.log(value);
    }, function (reason) {
      console.error(reason);
    })

在这里插入图片描述

11.3 Promise.prototype…then 方法

    const p = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('用户数据');
        // reject('出错啦!');
      }, 1000)
    })

    // 调用 then 方法
    // p.then(value => {
    //   console.log(value);
    // }, reason => {
    //   console.warn(reason);
    // })

    // 调用 then 方法,then 方法的返回结果是 Promise 对象,对象状态由回调函数的执行结果决定
    // 如果回调函数中返回的结果是 非 Promise 类型的属性  状态为成功
    // const result = p.then(value => {
    //   // console.log(value);
    //   // 1. 非 Promise 类型的属性
    //   // return 'hello';    //[[PromiseResult]]: undefined
    //   // 2. 是 Promise 对象
    //   // return new Promise((resolve, reject) => {
    //   //   resolve("ok");
    //   // });
    //   // 3. 抛出错误
    //   // throw new Error('出错啦');
    //   throw "出错啦";
    // }, reason => {
    //   console.warn(reason);
    // })

    // 链式调用
    p.then(value => {

    }).then(value => {

    }, reason => {

    })

11.4 案例(链式调用封装多个异步的任务)

    const fs = require('fs');

// fs.readFile('./resources/hello1.txt', (err, data1) => {
//   fs.readFile('./resources/hello2.md', (err, data2) => {
//     fs.readFile('./resources/hello3.txt', (err, data3) => {
//       let result = data1 + '\r\n' + data2 + '\r\n' + data3;
//       console.log(result);
//     });
//   });
// });

// 使用 Promise 实现
const p = new Promise((resolve, reject) => {
  fs.readFile('./resources/hello1.txt', (err, data) => {
    resolve(data);
  });
});

p.then((value) => {
  return new Promise((resolve, reject) => {
    fs.readFile('./resources/hello2.md', (err, data) => {
      resolve([value, data]);
    });
  });
})
  .then((value, reason) => {
    return new Promise((resolve, reject) => {
      fs.readFile('./resources/hello3.txt', (err, data) => {
        // 压入
        value.push(data);
        resolve(value);
      });
    });
  })
  .then((value) => {
    console.log(value.join('\r\n'));
  });

在这里插入图片描述

11.4catch

    const p = new Promise((resolve, reject) => {
      setTimeout(() => {
        // 设置 p 对象的状态为失败,并设置失败的值
        reject("出错啦")
      }, 1000)
    });

    // p.then(function (value) { }, function (reason) {
    //   console.error(reason);
    // })

    p.catch(reason => {
      console.warn(reason);
    })

十二、集合与 API

12.1 Set

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

  1. size 返回集合的元素个数

  2. add 增加一个新元素,返回当前集合

  3. delete 删除元素,返回boolean

  4. has 检测集合中是否包含某个元素,返回boolean

     // 声明一个 set
    let s = new Set();
    console.log(s, typeof s);

在这里插入图片描述

    let s = new Set(['西游记', '水浒传', '红楼梦', '三国', '西游记']);
    // 自动去重
    console.log(s);
    // 元素个数
    console.log(s.size);
    // 添加元素
    s.add("封神榜");
    console.log(s);
    // 删除
    s.delete("水浒传");
    console.log(s);
    // 检测
    console.log(s.has('水浒传'));
    console.log(s.has("三国"));
    // 清空
    // s.clear();
    // console.log(s);

    for (let v of s) {
      console.log(v);
    }

在这里插入图片描述

12.2 Set案例

    let arr1 = [1, 2, 3, 4, 5, 4, 2, 1];

    // 1. 数组去重
    // let result = [...new Set(arr1)];
    // console.log(result);

    // 2. 交集
    let arr2 = [4, 5, 6, 4, 5];
    // let result = [...new Set(arr1)].filter(item => {
    //   let s = new Set(arr2);
    //   if (s.has(item)) {
    //     return true;
    //   } else {
    //     return false;
    //   }
    // });
    // 简写
    // let result = [...new Set(arr1)].filter(item => new Set(arr2).has(item));
    // console.log(result);

    // 3. 并集
    // let union = [...new Set([...arr1, ...arr2])];
    // console.log(union);

    // 4. 差集
    let diff = [...new Set(arr1)].filter(item => !(new Set(arr2).has(item)));
    console.log(diff);

12.3 Map

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

  1. size 返回 Map的元素个数

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

  3. get 返回键名对象的键值

  4. has 检测Map中是否包含某个元素,返回boolean

  5. clear 清空集合,返回undefined

    // 声明 Map
    let m = new Map();
    // console.log(m, typeof m);

    // 添加元素
    m.set('name', '张三');
    m.set('change', function () {
      console.log("改变一下");
    });
    let key = {
      school: '清华',
    };

    m.set(key, ['北京', '上海', '深圳']);
    console.log(m);

    // size
    console.log(m.size);

    // 删除
    m.delete('name');
    console.log(m);

    // 获取
    console.log(m.get('change'));
    console.log(m.get(key));

    // 遍历
    for (let v of m) {
      console.log(v);
    }

    // 清空
    m.clear();
    console.log(m);

十二、class

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

知识点

  1. class 声明类

  2. constructor 定义构造函数初始化

  3. extends继承类

  4. super调用父级的构造方法

  5. static定义静态方法和属性

  6. 父类方法可以重写

12.1 class介绍与体验

    // ES5 构造函数实例化对象
    // 手机
    function Phone(brand, price) {
      this.brand = brand;
      this.price = price;
    }

    // 添加方法
    Phone.prototype.call = function () {
      console.log("打电话");
    }

    // 实例化对象
    let Huawei = new Phone("华为", 5999);
    Huawei.call();
    console.log(Huawei);

    // ES6 class 实例化对象
    class Shouji {
      // 构造方法 名字不能修改
      constructor(brand, price) {
        this.brand = brand;
        this.price = price;
      }
      // 方法必须使用该语法,不能使用 ES5 的对象完整形式
      call() {
        console.log("我可以打电话");
      }
    }

    // 实例化
    let OPPO = new Shouji("OPPO", 4999);
    OPPO.call();
    console.log(OPPO);

在这里插入图片描述

12.2 静态成员

    // 静态成员
    // function Phone() {

    // }
    // // 静态属性
    // // 属于函数对象,不属于实例属性
    // Phone.name = "手机";
    // Phone.netPlay = function () {
    //   console.log("我能上网");
    // }

    // Phone.prototype.size = '5.5inch';

    // let vivo = new Phone();
    // console.log(vivo.name);  // undefined
    // // vivo.netPlay();   //报错

    // console.log(vivo.size);

    class Phone {
      // 静态属性
      static name = '手机';
      static netPlay() {
        console.log("我能上网");
      }
    }

    let onePlus = new Phone();
    console.log(onePlus.name);
    console.log(Phone.name);

在这里插入图片描述

12.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, size);
    //   this.color = color;
    //   this.size = size;
    // }

    // // 设置子级构造函数原型
    // SmartPhone.prototype = new Phone;
    // SmartPhone.prototype.constructor = SmartPhone;  //可不写

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

    // SmartPhone.prototype.play = function () {
    //   console.log("我可以打游戏");
    // }

    // const chuizi = new SmartPhone("锤子", 2499, "黑色", "5.5inch");
    // console.log(chuizi);

    // 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("玩游戏");
      }

      //  子类对父类方法的重写
      call() {
        // super();  //报错
        console.log("我可以视频通话");
      }
    }

    const xiaomi = new SmartPhone('小米', 999, '黑色', '4.7inch');
    console.log(xiaomi);
    xiaomi.call();  // 调用的是子类的call方法,如果子类没有该方法,调用父级的该方法
    xiaomi.photo();
    xiaomi.playGame();

在这里插入图片描述

12.4 getter 和 setter

    class Phone {
      get price() {
        console.log("价格被读取了");
        return '999';
      }

      set price(newVal) {
        console.log("价格被修改了");
      }
    }

    // 实例化对象
    let s = new Phone();
    console.log(s.price);
    s.price = 'free';

在这里插入图片描述

十三、数值扩展

13.1 Number.EPSILON

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

    console.log(0.1 + 0.2 === 0.3); // false

    function equal(a, b) {
      if (Math.abs(a - b) < Number.EPSILON) {
        return true;
      } else {
        return false;
      }
    }

    console.log(equal(0.1 + 0.2, 0.3));

在这里插入图片描述

13.2 进制

    // 二进制
    let b = 0b1010;
    console.log(b);

    // 八进制
    let o = 0o777;
    console.log(o);

    // 十进制
    let d = 100;
    console.log(d);

    // 十六进制
    let x = 0xff;
    console.log(x);

在这里插入图片描述

13.3 Number.isFinite

Number.isFinite 检测一个数值是否为有限数

    console.log(Number.isFinite(100));
    console.log(Number.isFinite(100 / 0));
    console.log(Number.isFinite(Infinity));

在这里插入图片描述

13.4 Number.isNaN

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

console.log(Number.isNaN(123)); // false

在这里插入图片描述

13.5 Number.parseInt 和 Number.parseFloat

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

    console.log(Number.parseInt('2022haha'));
    console.log(Number.parseFloat('3.1415926嘿嘿'));

在这里插入图片描述

13.6 Number.isInteger

Number.isInteger 判断一个数是否为整数

    console.log(Number.isInteger(5));
    console.log(Number.isInteger(5.12));

在这里插入图片描述

13.7 Math.trunc

将数字的小数部分抹掉

console.log(Math.trunc(3.5));

在这里插入图片描述

13.8 Math.sign

判断一个数是 正数(1) 负数(-1) 还是零(0)

    console.log(Math.sign(100));
    console.log(Math.sign(0));
    console.log(Math.sign(-10));

在这里插入图片描述

十四、对象方法扩展

14.1 Object.is

Object.is 判断两个值是否完全相等

    console.log(Object.is(10, 10));  // 类似于 ===
    console.log(Object.is(NaN, NaN));
    console.log(NaN === NaN);

在这里插入图片描述

14.2 Object.assign

对象的合并

    const config1 = {
      host: 'localhost',
      port: 3306,
      name: 'root',
      password: 'root',
      test: 'test'
    }

    const config2 = {
      host: '127.0.0.1',
      port: 3307,
      name: 'admin',
      password: 123456,
      demo: 'demo'
    }

    console.log(Object.assign(config1, config2));

在这里插入图片描述

14.3 Object.setPrototypeOf 和 Object.getPrototypeOf

Object.setPrototypeOf 设置原型对象 Object.getPrototypeOf 获取原型

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

在这里插入图片描述

十五、模块化

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

15.1 优点:

  • 防止命名冲突

  • 代码复用

  • 高维护性

15.2 模块化规范产品

ES6 之前的模块化规范有:

  1. CommonJS => NodeJS、Browserify

  2. AMD => requireJS

  3. CMD => seaJS

15.3 ES6 模块化语法

模块功能由两个命令构成:exportimport

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

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

m1.js

// 分别暴露
export let name = '张三';
export function fn() {
  console.log('我是好人');
}

m2.js

// 统一暴露
let name = '李四';
function fn() {
  console.log('我是好人');
}

export { name, fn };

m3.js

// 默认暴露
export default {
  name: '王麻子',
  haoren: function () {
    console.log('我也是好人');
  },
};
    <script type="module">
    // 1. 通用导入方式
    // 引入 m1 模块内容
    // import * as m1 from "./resources/m1.js";

    // 引入 m2 模块内容
    // import * as m2 from "./resources/m2.js";

    // 引入 m3 模块内容
    // import * as m3 from "./resources/m3.js";

    // console.log(m1);
    // console.log(m2);
    // console.log(m3);
    // m3.default.haoren();

    // 2. 解构赋值形式
    // import { name, fn } from "./resources/m1.js"
    // console.log(name);
    // console.log(fn);

    // import { name as lisi, fn as haoren } from "./resources/m2.js"
    // console.log(lisi);
    // console.log(haoren);

    // import { default as m3 } from "./resources/m3.js"
    // console.log(m3);

    // 简写形式,针对默认暴露
    // import m3 from "./resources/m3.js"
    // console.log(m3);
    </script>

app.js

// 入口文件

import * as m1 from './m1.js';
import * as m2 from './m2.js';
import * as m3 from './m3.js';

console.log(m1);
console.log(m2);
console.log(m3);
<script src="./resources/app.js" type="module"></script>

十六、babel

Babel 是一个 JavaScript 编译器,能够将 ES6 新的语法转换为浏览器能识别的 ES5 的语法

16.1 安装工具

  • babel-cli babel命令行工具

  • babel-preset-env 预设包,能够把新的 ES 特性转换为 ES5

  • browserify 打包工具,项目中一般使用 webpack

cnpm init --yes
// 安装工具
cnpm i babel-cli babel-preset-env browserify -D
// 语法转换
npx babel js -d dist/js --presets=babel-preset-env
// 打包
npx browserify dist/js/app.js -o dist/bundle.js

在这里插入图片描述

16.2 引入 npm 包

cnpm i jquery
// 修改背景为粉色
import $ from 'jquery';
$('body').css('background', 'pink');

在这里插入图片描述

十七、ES7 新特性

17.1 Array.prototype.includes

Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值

    // includes  indexOf
    const mingzhu = ['西游记', '水浒传', '红楼梦', '三国'];

    // 判断
    console.log(mingzhu.includes('西游记'));
    console.log(mingzhu.includes('金瓶梅'));

在这里插入图片描述

17.2 指数操作符

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

    // ** 幂运算
    console.log(2 ** 10)
    console.log(Math.pow(2, 10));;

在这里插入图片描述

十八、ES8 新特性

18.1 async 和 await

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

18.1.1 async 函数

  1. async 函数的返回值为 promise 对象

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

     async function fun() {
      // console.log("hello world");
      // 返回字符串
      // return 'hello world';
      // 返回的结果不是一个 Promise 类型的对象,返回的结果就是成功的 Promise 对象
      // return;
      // 抛出错误,返回的结果是一个失败的 Promise
      // throw new Error('出错啦!');
      // 返回的结果是 Promise 对象
      return new Promise((resolve, reject) => {
        resolve('成功的数据');
        // reject('失败的错误');
      })
    }

    const result = fun();
    console.log(result);

    // 调用 then 方法
    result.then(value => {
      console.log(value);
    }, reason => {
      console.warn(reason);
    })

18.1.2 await 表达式

  1. await 必须写在 async 函数中

  2. await 右侧的表达式一般为 promise 对象

  3. await 返回的是 promise 成功的值

  4. await 的 promise 失败了,就会抛出异常,需要通过 try…catch 捕获处理

    // 创建 Promise 对象
    const p = new Promise((resolve, reject) => {
      // resolve('成功的值');
      reject('失败啦!');
    })

    // await 要放在 async 函数中
    async function main() {
      try {
        let result = await p;
        console.log(result);
      } catch (error) {
        console.log(error);
      }
    }

    // 调用 main 函数
    main();

18.1.3 async与await结合读取文件内容

// 引入 fs 模块
const fs = require('fs');

// 读取内容
function readHello1() {
  return new Promise((resolve, reject) => {
    fs.readFile('./hello1.txt', (err, data) => {
      // 失败
      if (err) reject(err);
      // 成功
      resolve(data);
    });
  });
}

function readHello2() {
  return new Promise((resolve, reject) => {
    fs.readFile('./hello2.md', (err, data) => {
      // 失败
      if (err) reject(err);
      // 成功
      resolve(data);
    });
  });
}

function readHello3() {
  return new Promise((resolve, reject) => {
    fs.readFile('./hello3.txt', (err, data) => {
      // 失败
      if (err) reject(err);
      // 成功
      resolve(data);
    });
  });
}

// 声明一个 async 函数
async function main() {
  let hello1 = await readHello1();
  let hello2 = await readHello2();
  let hello3 = await readHello3();

  console.log(hello1.toString());
  console.log(hello2.toString());
  console.log(hello3.toString());
}

main();

18.1.4 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)
            }
          }
        }
      })
    }

    // 测试
    // const result = sendAjax("https://api.apiopen.top/api/getImages");
    // console.log(result);

    // Promise then 方法测试
    // sendAjax("https://api.apiopen.top/api/getImages").then(value => {
    //   console.log(value);
    // }, reason => { })

    // async 与 await 测试
    async function main() {
      let result = await sendAjax("https://api.apiopen.top/api/getImages");
      console.log(result);
    }
    main()

在这里插入图片描述

18.2 ES8 对象方法扩展

    const school = {
      name: '尚硅谷',
      cities: ['北京', '上海', '深圳'],
      xueke: ['前端', '后端', '大数据', '运维']
    };

    // 获取所有对象的键
    console.log(Object.keys(school));
    // 获取所有对象的值
    console.log(Object.values(school));
    // entries
    console.log(Object.entries(school));
    // 创建 Map
    const m = new Map(Object.entries(school));
    console.log(m.get('cities'));

    // 对象属性的描述对象
    console.log(Object.getOwnPropertyDescriptors(school));
    const obj = Object.create(null, {
      name: {
        // 设置值
        value: '尚硅谷',
        // 属性特性
        writable: true,
        configurable: true,
        enumerable: true
      }
    })

在这里插入图片描述

十九、ES9

19.1 rest参数

Rest参数与 spresd 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了想数组一样的 rest 参数和扩展运算符

    function content({ host, port, username, password }) {
      console.log(host);
      console.log(port);
      console.log(username);
      console.log(password);
    }

    content({
      host: '127.0.0.1',
      port: '8080',
      username: 'admin',
      password: '123456'
    })

在这里插入图片描述

    function content({ host, port, ...user }) {
      console.log(host);
      console.log(port);
      console.log(user);
    }

    content({
      host: '127.0.0.1',
      port: '8080',
      username: 'admin',
      password: '123456',
      type: 'master'
    })

在这里插入图片描述

19.2 扩展运算符

    const skillOne = {
      q: '天音波'
    }
    const skillTwo = {
      w: '金钟罩'
    }
    const skillThree = {
      e: '天雷破'
    }
    const skillFour = {
      r: '猛龙摆尾'
    }

    const mangseng = { ...skillOne, ...skillTwo, ...skillThree, ...skillFour }
    console.log(mangseng);

在这里插入图片描述

19.3 正则扩展-命名捕获分组

    // 声明一个字符串
    let str = '<a href="http://www.atguigu.com">尚硅谷</a>';

    // 提取 url 与 标签文本
    const reg = /<a href="(.*)">(.*)<\/a>/;

    // 执行
    const result = reg.exec(str);

    console.log(result);

    console.log(result[1]);
    console.log(result[2]);

在这里插入图片描述

    let str = '<a href="http://www.atguigu.com">尚硅谷</a>';

    const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;

    const result = reg.exec(str);

    console.log(result);

在这里插入图片描述

19.4 正则扩展-反向断言

    let str = 'js123456哈哈哈666嘿嘿嘿';

    // 正向断言
    // const reg = /\d+(?=嘿)/;

    // const result = reg.exec(str);
    // console.log(result);

    // 反向断言
    const reg = /(?<=哈)\d+/;

    const result = reg.exec(str);
    console.log(result);

在这里插入图片描述

19.5 正则扩展-dotAll模式

    // dot . 元字符  除换行符以外的任意单个字符
    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 result = reg.exec(str);
    // console.log(result);

    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);

在这里插入图片描述

二十、ES10

20.1 对象扩展方法 Object.fromEntries

    // 二维数组
    const result = Object.fromEntries([
      ['name', '尚硅谷'],
      ['xueke', '测试,前端,后端,大数据。人工智能']
    ]);
    console.log(result);

    // Map
    const m = new Map();
    m.set('name', '张三');
    const result2 = Object.fromEntries(m);
    console.log(result2);

    // Object.entries  ES8
    const arr = Object.entries({
      name: '李四'
    })
    console.log(arr);

在这里插入图片描述

20.2 字符串方法扩展 trimStart 与 trimEnd

    let str = '   HelloWorld  '
    console.log(str);
    console.log(str.trim());
    console.log(str.trimStart());
    console.log(str.trimEnd());

在这里插入图片描述

20.3 数组方法扩展flat与flatMap

    // flat 平
    // 将多维数组转换为低维数组
    const arr = [1, 2, 3, [4, 5, 6]]
    console.log(arr);
    console.log(arr.flat());

    const arr2 = [1, 2, 3, [4, 5, 6, [7, 8, 9]]]
    console.log(arr2.flat());
    // 参数为深度,默认为 1
    console.log(arr2.flat(2));

    // flatMap
    const arr3 = [1, 2, 3];
    const result = arr3.map(item => item * 10);
    console.log(result);

    const arr4 = [1, 2, 3];
    const result2 = arr3.map(item => [item * 10]);
    console.log(result2);

    const arr5 = [1, 2, 3];
    const result3 = arr3.flatMap(item => [item * 10]);
    console.log(result3);

在这里插入图片描述

20.4 Symbol.prototype.description

    // 创建 Symbol
    let s = Symbol('Hello World')
    console.log(s.description);

在这里插入图片描述

二十一、ES11

21.1 私有属性

    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);
        console.log(this.#weight);
      }
    }

    const girl = new Person('晓红', 18, '45kg');
    console.log(girl);
    console.log(girl.name);
    console.log(girl.age);
    console.log(girl.weight);

    girl.intro();

    // console.log(girl.#age);
    // console.log(girl.#weight);

在这里插入图片描述

21.2 Promise.allSettled方法

    // 声明两个 promise 对象
    const p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('商品数据 - 1')
      }, 1000)
    })

    const p2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        // resolve('商品数据 - 2')
        reject('出错啦')
      }, 1000)
    })

    // 调用 allsettled 方法
    const result = Promise.allSettled([p1, p2])
    console.log(result);

    const res = Promise.all([p1, p2])
    console.log(res);

在这里插入图片描述

21.3 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);
    // }

    const arr = [...result];
    console.log(arr);

在这里插入图片描述

21.4 可选链操作符

    function main(config) {
      const dbhost1 = config && config.db && config.db.host
      console.log(dbhost1);

      const dbhost2 = config?.db?.host
      console.log(dbhost2);
    }

    main({
      db: {
        host: '192.168.1.100',
        username: 'root'
      },
      caches: {
        host: '192.168.1.200',
        username: 'admin'
      }
    })

在这里插入图片描述

21.5 动态 import

html

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

ES11app.js

// import * as h1 from './ES11hello.js'
const btn = document.getElementById('btn');
btn.onclick = function () {
  import('./ES11hello.js').then((module) => {
    // console.log(module);
    module.hello();
  });
};

ES11hello.js

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

21.6 BigInt 类型

    // 大整形
    let n1 = 521n;
    console.log(n1, typeof (n1));

    // 函数
    let n2 = 123;
    console.log(BigInt(n2));
    // console.log(BigInt(1.2));  //报错,不是整数

    // 大数值运算
    let max = Number.MAX_SAFE_INTEGER;
    console.log(max);
    console.log(max + 1);
    console.log(max + 2);

    console.log(BigInt(max) + BigInt(1));
    console.log(BigInt(max) + BigInt(2));

在这里插入图片描述

21.7 绝对全局对象 globalThis

console.log(globalThis);

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值