ES6常用

120 阅读4分钟

模板字符串

var name = "lilei"
const str = `${name}:是小学生`;

let、const

var的问题
  • 声明提前,打乱程序正常的执行顺序
  • 没有块级作用域的概念
var t = 0;
function fun1() {
    t += 2;
}
function fun2() {
    t += 1;
}
fun1();
fun2();
console.info(t);

上面的例子,在fun1和fun2执行完成后,变成了3.这个结果是正常的。再往下看

var t = 0;
function fun1() {
    t += 2;
    // 这里加入了一个不会执行的代码段
    if (false) {
       var t = 999;
    }
}
function fun2() {
    t += 1;
}
fun1();
fun2();
console.info(t);

如上面所示,在fun1中加入了一个不会执行的代码,但是执行完以后,t变成了1

fun1中就因为存在声明提升才会导致这样的结果.fun1中

function fun1() {
    var t; // !! 注意这里
    t += 2;
    if (false) {
        t = 999;
    }
}
let本质

相当于匿名函数自调

(function() {

})();
let三个小脾气
  • 因为不会声明提升,所以不能在声明前使用,所以有临时死区
  • 在相同作用域内,禁止声明两个相同的变量
  • 因为let底层相当于匿名函数自调,所以即使在全局创建的let变量,在window中也找不到

箭头函数

const fun1 = () => {
    console.info("log");
}
不能使用箭头函数的地方
  • 构造函数不能用(因为this)
  • 对象的方法不能用(因为this)
var name = "123"
var obj = {
    name: "345",
    getName: function() {
        console.info(this.name)
    },
    getName2: () => {
        console.info(this.name)
    }
}
obj.getName(); // 345
obj.getName2(); // 123
  • 原型对象方法不能用(因为this)
  • DOM中事件处理函数不能用(因为this)
  • 箭头函数无法用call,apply,bind改变this
  • 箭头函数不支持arguments
  • 箭头函数没有prototype

for of

未来,当遇到索引数组类数组对象时,就用for-of

索引数组
var list = ["蓝蓝", "红红", "绿绿"];
for (var name of list) {
    console.info(name)
}
类数组对象

这里讨论的是arguments

function fun1(value) {
    console.info(arguments)
    console.info(typeof arguments) // 对象
    console.info(Array.isArray(arguments)) // false
    for(var v of arguments){
        console.info(v)
    }
}
fun1("val")

上面代码就能判断出,arguments是一个对象,但是是类数组对象

函数的参数增强

参数默认值
    function fun1(val = "defaultValue") {
        console.info(val)
    }
    fun1();
    fun1("传入的参数");
剩余参数(rest)

注意:rest是数组

function add(...rest) {
    console.info(rest)
    console.info(Array.isArray(rest)) // true
    return rest.reduce((a, b) => a + b)
}
add(1, 2, 4, 5)

解构

  • 数组解构
var arr = [2022, 3, 4];
var [y, m, d] = arr;
  • 对象解构
var obj = {
    y: 2022,
    m: 3,
    d: 4,
}
var { y, m, d } = obj;

class和继承

class本质是构造函数

class Student {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    // intr保存在原型对象中
    intr() {
        console.info(this.name)
    }
}
var lilei = new Student("lilei", 12)

直接放在class对象中的方法,就是原型对象方法

class实例.jpg

多个对象共用的相同属性值,应该放在哪?

注意问的是属性值

答案是:原型对象(prototype)上

class中的问题

直接在class中定义的方法,都默认保存在原型对象中。

但是直接在class中定义的属性,却不会成为公共属性,不会保存在原型对象

    class Student {
        className = "二(8)班"
    }
    var lilei = new Student();

class.jpg 从上面可以看到,className属性是放在实例上的

解决办法

使用静态属性

标有static的属性,都存在构造函数

    class Student {
        static className = "二(8)班",
        intr() {
            console.info(this.className); // undefined
            console.info(Student.className); // 通过类型名访问静态属性
        }
    }
    var lilei = new Student();

class3.jpg

4444.jpg

注意看上图,static className到底存在哪?是Student这个构造函数身上

另外:上面代码有标注,如果想访问静态属性值,不可以通过this.静态属性。只能通过类型名.静态属性

继承(extends)
  • 先有子类型还是先有父类型?

答:现有子类型,发现子类型重复了,再去抽象父类型

super
  1. super是专门指向父类型的关键字
  2. 调用super()等于调用父类型的构造函数
  3. 调用爷爷类型的构造函数,等效于执行爷爷类型的构造函数中共有的"this.xxx=xxx"语句

Promise

多个异步任务顺序执行

new Promise((resolve, rejected) => {
   // do something 
   if(xxx) {
       resolve(123);
   } else {
       rejected(444)
   }
}).then((res) => {
    console.info(res) // 123
}).catch((error) => {
    console.error(error) // 444
})
async await
  1. 只有基于Promise的函数,才支持async和await
  2. await必须用在被async标记的函数中
  3. 外层函数必须用async标记,目的是告诉主程序,这段函数内的代码整体是异步执行的,不影响主程序的执行
  4. await必须写在前一项任务之前
  5. await的作用等效于.then()。用来通知程序必须等待前一项任务执行完,才能继续执行后续任务
  6. 一旦使用await,前一项任务的resolve返回值,可以像普通函数一样用 = 接住,后续代码可继续使用该变量里获得的返回值
async function test() {
    var result = new Promise方法
    console.info(result)
}
test()
  1. await和.then()一样,可多次使用,控制多个异步顺序执行
为什么函数前要用async标记

因为整个外层函数,相对于主程序,整个函数应该是异步的,不应该影响主程序。

同时告诉函数内的await,你们几个应该是同步

错误处理

使用try catch

手写Promise

gitee代码