• ECMAScript6


    课程链接

    相关介绍

    什么是ECMA

    中文名称是欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。

    什么是ECMAScript

    是Ecma通过ECMA-262标准化的脚本程序设计语言

    为什么学习ES6

    • ES6的版本变动内容最多,具有里程碑意义
    • ES6加入许多新的语法特性,变成实现更简单
    • ES6是前端发展趋势,就业必备技能

    let

    • 声明变量
    // 声明变量
    let a;
    let b,c;
    let e = 100;
    let f = 100, g = 200,h = [];
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 变量不能重复声明
    • 块级作用域
      只在代码块里有效
    • 不存在变量提升
    console.log(name); // undefined
    var name = "qiu";
    
    • 1
    • 2
    console.log(name); // 报错
    let name = "qiu";
    
    • 1
    • 2
    • 不影响作用域链

    const

    • 声明常量
    // 声明常量
    const AGE = 18;
    console.log(AGE);
    
    • 1
    • 2
    • 3
    • 一定要赋初始值
    • 一般常量使用大写
    • 常量值不能修改
    • 块级作用域
    • 对于数组和对象的元素修改,不算做对常量的修改,不会报错(引用地址并没有变)

    变量解构赋值

    允许直接从数组和对象中提取值并赋值

    1. 数组的解构
    const hobby = ["吃","喝","玩","乐"];
    let [h1,h2,h3,h4]= hobby;
    console.log(h1); //"吃"
    console.log(h2); //"喝"
    console.log(h3); //"玩"
    console.log(h4); //"乐"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. 对象的解构
    const person = {
        name: "Peter",
        age: 12,
        sleep(){
            console.log("zzzzzzzz");
        }
    }
    let {name, age, sleep} = person;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    模板字符串

    • 声明
    // 模板字符串
    let str = `模板字符串`
    
    • 1
    • 2
    • 内容中可以直接出现换行符
    let str2 = `
    • 苹果
    • 香蕉
      • `;
        • 1
    • 变量拼接
    const fruits = ["苹果","香蕉","橘子","梨"];
    let str3 = `我喜欢吃${fruits[2]}`;
    
    • 1
    • 2

    对象简化写法

    // 对象简化写法
    let name = "lisa";
    let sex = 1;
    const student = {
        name,
        sex
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    箭头函数

    // 箭头函数
     let fn = (a,b) =>{
         return a + b;
     }
    
    • 1
    • 2
    • 3
    • 4

    特性:

    1. this是静态的,this始终指向函数声明时所在作用域下的this值 (没有自己的this,指向外部this)
    let getName = ()=>{
       console.log(this.name);
    }
    function getName2() {
        console.log(this.name);
    }
    window.name = "window";
    const school = {
        name:"TUST",
    }
    
    getName(); //"window"
    getName2(); //"window"
    getName.call(school); //"window"
    getName2.call(school); //"TUST"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 不能作为构造函数实例化对象
    2. 不能使用arguments变量
    3. 箭头函数的简写
      1)当形参有且只有一个的时候,可以省略小括号
    let add = n => {
      return n + 1;
    }
    
    • 1
    • 2
    • 3

    2)当代码题只有一条语句的时候,可以省略花括号
    此时return也必须省略,且语句的执行结果就是函数的返回值

    let add = n => n + 1;
    
    • 1

    函数参数的默认值

    • 一般把有初始值的形参放到最后
    // 允许给函数参数赋值初始值
    function add(a,b,c = 10) {
        return a + b + c;
    }
    add(1,3); //14
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 与结构赋值结合使用
    // 结合结构赋值使用
    functionconnect({host, username, pass, port=3306}) {
        console.log(host, username, pass, port);
    }
    connectInfo = {
        host: "localhost",
        username: "root",
        pass: "root",
        port: 8080
    }
    connect(connectInfo);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    rest参数

    用于获取函数的实参,同来代替arguments
    与arguments不同的是,arguments是对象,rest是数组
    有多个rest参数必须放到最后function date(a,b,...args){}

    function date(...args){
       console.log(args); // ['苹果', '香蕉', '橘子', '梨']
    }
    date("苹果","香蕉","橘子","梨");
    
    • 1
    • 2
    • 3
    • 4

    扩展运算符

    将数组转换为逗号分隔的参数序列

    const fruits = ['苹果', '香蕉', '橘子', '梨'];
    date(...fruits); // 等同于date("苹果","香蕉","橘子","梨");
    
    • 1
    • 2

    Symbol

    Symbol特点

    1. Symbol的值是唯一的,用来解决命名冲突的问题
    2. Symbol值不能与其他数据进行运算
    3. Symbol定义的对象属性不能使用for…in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
    let s = Symbol();
    console.log(s,typeof s); //Symbol() 'symbol'
    
    • 1
    • 2

    迭代器

    工作原理

    1. 创建一个指针对象,指向当前数据结构的起始位置
    2. 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
    3. 接下来不断调用next方法,指针一直往后移动,直到指向最有一个成员
    4. 每调用next方法返回一个包含value和done属性的对象

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

    原生具备iterator接口的数据(可用for of 遍历)
    Arrary、Arguments、Set、Map、String、TypedArray、NodeList

    const fruits = ['苹果', '香蕉', '橘子', '梨'];
    
    let iterator = fruits[Symbol.iterator](); //获取迭代器对象
    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: 'undefined', done: true}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    生成器函数与调用

    生成器其实就是一个特殊的函数

    function * gen(){
        console.log("Hello generator");
        yield "abcdefg"; //可以看成函数分隔符
        //-----------------------------------------
        console.log("How are you?");
        yield "hijklmn";
        //-----------------------------------------
        console.log("I am fine. Thank you!");
        let str = yield "opqrst";
        //-----------------------------------------
        console.log(str); 
    }
    let iterator = gen();
    // console.log(iterator); //gen {}
    iterator.next(); //Hello generator
    console.log(iterator.next()); //How are you? {value: 'hijklmn', done: false}
    iterator.next(); //I am fine. Thank you!
    iterator.next("Bye bye"); //Bye bye
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    Promise

    介绍与基本用法

    const p = new Promise(function(resolve, reject){
        setTimeout(function(){
            // 成功情况
            // let data = "数据库中数据";
            // resolve(data); //执行成功回调
    
            // 失败情况
            let msg = "网络连接失败";
            reject(msg); //执行失败回调
        },1000)
    })
    
    // 调用Promise对象的then方法a
    p.then(function(data){
        console.log("成功回调!!!",data);
    },function(error){
        console.log("失败回调。。。。。",error);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    Promise封装读取文件

    const fs = require('fs');
    
    const p = new Promise(function(resolve, reject){
        fs.readFile("./resources/readme.txt",(err,data)=> {
            // 如果失败,则执行错误回调
            if (err) reject(err);
            // 如果成功,则执行成功回调
            resolve(data);
        });
    })
    
    p.then(function(value){
        console.log(data.toString());
    },function(reason) {
        console.log("获取失败",reason);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Promise.prototype…then方法

    之前的例子

    const p = new Promise(function(resolve, reject){
        setTimeout(function(){
            // 成功情况
            // let data = "数据库中数据";
            // resolve(data); //执行成功回调
    
            // 失败情况
            let msg = "网络连接失败";
            reject(msg); //执行失败回调
        },1000)
    })
    
    // 调用Promise对象的then方法
    p.then(function(data){
        console.log("成功回调!!!",data);
    },function(error){
        console.log("失败回调。。。。。",error);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    p.then方法返回的是一个Promise对象,对象中有两个是,一个是PromiseState一个是PromiseResult
    这两个属性,根据回调内容不同而不同

    // 调用Promise对象的then方法
    let pThen =p.then(function(data){
        console.log("成功回调!!!",data);
        // 1. 返回非Promise类型值,PromiseState为fulfilled,PromiseResult为undefined
        // return data;
        // 2. 返回非Promise类型值,PromiseState为该Promise的成功或失败结果,PromiseResult为结果参数
        // return new Promise(function(resolve,reject){
        //     resolve(123)
        // })
        // 3. 抛出错误,PromiseState为rejected,PromiseResult为抛出的错误
        throw "err";
    },function(error){
        console.log("失败回调。。。。。",error);
    })
    console.log(pThen);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    比如,此时结果就如下
    在这里插入图片描述
    可以通过在then中返回Promise进行链式调用,杜绝回调地狱问题

    Promise.catch方法

    就相当于then方法,不写第一个回调

    p.catch(function(reason) {
        console.warn(reson);
    })
    
    • 1
    • 2
    • 3

    Set

    自动去重

    // Set
    let s= new Set(["苹果","香蕉","橘子","梨","橘子"]);
    console.log(s); //Set(4) {'苹果', '香蕉', '橘子', '梨'}
    // 元素格式
    s.size;
    // 添加元素
    s.add("葡萄");
    // 删除元素
    s.delete("橘子");
    // 检测
    s.has("西瓜");
    // 清空
    s.clear();
    // 循环 实现了iterator迭代器接口可以用forof
    for (const iterator of s) {
        console.log(iterator);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Map

    键值对集合

    // Map
    let m =new Map();
    // 添加元素
    m.set("name","qiu");
    m.set({name:"qiu"},{obj:null});
    // 键值对个数
    m.size;
    // 获取
    m.get("name");
    // 删除
    m.delete("name");
    // 清空
    m.clear();
    // 遍历 实现了iterator接口
    for (const iterator of m) {
        console.log(m);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    class类

    介绍与初体验

    对比一下ES5和ES6创建实例对象

    // class
    // ES5
    function Phone(brand, price){
        this.brand = brand;
        this.price = price;
    }
    // 通过原型对象添加方法
    Phone.prototype.open = function(){
        console.log("dangdangdangdang~");
    }
    // 实例化对象
    let Huawei = new Phone('华为',5999);
    
    // ES6
    class Phone {
        // 构造方法 名字不能修改
        constructor(brand, price){
            this.brand = brand;
            this.price = price;
        }
        // 方法 不能使用open: function(){}形式
        open(){
            console.log("dangdangdangdang~");
        }
    
    }
    let Vivo = new Phone("Vivo",3999);
    
    • 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
    • 27

    静态成员

    属于类的属性,不属于实例对象

    class Phone {
        // 静态成员
        static classify = "数码设备";
    }
    
    • 1
    • 2
    • 3
    • 4

    类的继承

    ES5中的构造函数继承(父级就不写了,和上面一样)

    // ES5
    function AIPhone(brand, price, color, os) {
        Phone.call(this,brand,price);
        this.color = color;
        this.os = os;
    }
    // 设置子级构造函数的原型
    AIPhone.prototype = new Phone;
    AIPhone.prototype.constructor = AIPhone;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    ES6中类的继承

    // ES6
    class AIPhone extends Phone {
        constructor(brand, price, color, os) {
            super(brand,price); //父类构造函数
            this.color = color;
            this.os = os;    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    重写

    重写同名方法,当重写方法中不允许调用父类方法,只能直接覆盖

    get和set

    class Phone {
       // 构造方法 名字不能修改
       constructor(brand, price){
           this.brand = brand;
           this.price = price;
       }
       get color() {
           console.log("读取了color属性");
           return "黑色";
       }
       set color(newVal) {
           console.log("修改了color属性");
           // this.color = newVal;
       }
    }
    let vivoS9 = new Phone("Vivo",3999);
    console.log(vivoS9.color);
    vivoS9.color = "白色";
    console.log(vivoS9.color);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    ES6的数值扩展

    • Number.EPSILON是js表示的最小精度
    • 二进制和八进制:二进制0bxxx 八进制0oxxx 十进制xxx 十六进制0xxxx
    • Number.isFinite检测是否为有限数
    • Number.isNaN检测数值是否为NaN
    • Number.parseIntNumber.parseFloat字符串转为数字(整数/浮点数)
    • Number.isInteger判断是否为整数
    • Math.trunc将数字的小数部分抹掉
    • Math.sign判断一个数到底为正数(1)、负数(-1)还是零(0)

    对象方法扩展

    • Object.is 判断两个值是否完全相等(与===的区别 NaN===NaN为false)
    • Object.assign 两个对象的合并(相同的覆盖,不同的保留)
    • Object.setPrototypeOf设置原型对象 Object.getPrototypeOf获取原型对象 (不建议使用)

    模块化

    将大文件拆分为多个小文件,再组合
    优点:

    1. 防止命名冲突
    2. 代码复用
    3. 高维护性

    主要有两个命令构成:export暴露和import引用

    //test.js
    // 分别暴露
    export let school = "TUST";
    export let add = "TJ";
    
    //统一暴露
    let school = "TUST"
    let add = "TJ"
    export {school, add}
    
    // 默认暴露
    export default {
    	school: "TUST",
    	add: "TJ"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    //study.html
    //