最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • ES5 ES6 ES7

    正文概述 掘金(Kenguba)   2021-04-03   597

    ES6 语法

    es5 和 es6 声明变量的方式对比

    ES5中声明变量的方式:

    //1.通过var声明
    var num;
    
    //2.函数方式声明
    function fn(num){ return num; }
    fn(10);
    

    ES6中声明变量的方式:

    //1.使用let声明
    let a = 10;
    //2.使用const声明
    const name = "小红";
    

    var、let、const 的区别

    1. 不存在变量提升
      • var 命令会发生 变量提升 现象,即变量可以在声明之前使用,值为undefined
      • let 和 const 则没有变量声明提升的功能,必须要先声明才能使用
    2. 不允许重复声明
      • var命令能重复声明,后者覆盖前者
      • let 和 const不允许在相同作用域内,重复声明同一个变量
    3. 作用域
      • var 的作用域是以函数为界限
      • let 和 const 的作用域是块作用域,块级作用域指 { } 内的范围
      • var 可以定义全局变量和局部变量,let 和 const 只能定义局部变量
      • const 的声明的常量不能被修改,但对于引用类型来说,堆内存中的值是可以被改变的。
    4. 变量作为全局属性
      • var定义的变量会作为window对象的属性,而let不会

    ** 常量定义的引用类型可以修改

    //1.使用常量定义数组
            const arr = [100, 200, 300];
            console.log(arr);
            arr[0] = "hello";
            console.log(arr);   //['hello', 200, 300]
            //2.使用常量来定义对象
            const obj = {
                name: "Jack",
                age: 22,
                no: "001"
            }
            console.log(obj);
            obj.age = 100;
            console.log(obj);   //{name: "Jack", age: 100,  no: "001"}
    

    暂时性死区 定义:块级作用域内存在let命令时,所声明的变量就“绑定”这个区域,不再受外部的影响

    {
        //let a 之前的区域成为暂时性死区,调用a 会报错
        let a = "hello";
    }
    

    for循环中的作用域问题

    //设置循环变量的部分是父级作用域,而循环体内部是一个单独的子作用域。
    //ES6 中引用变量采用就近原则
    

    变量的解构

    本质:模式匹配
       1. 完全解构:模式完全匹配
       2. 不完全解构:模式不完全匹配
         - 为解构变量设置默认值,不会出现 undefined 的现象
         - 解构成功时,解构变量的默认值会被覆盖
         - 解构不成功时,解构变量的值为默认值
       
      对象的解构注意:
        1.对象在解构时,变量名要与属性名一致
        2.对象解构的解构变量不考虑顺序
        3.对象在解构时,为对象属性重命名,可以方便程序的编写。注:重命名不会更改对象的属性
        4.和解构数组一样,解析对象时可以设置默认值 outLookURL:url = 111
    

    函数添加参数的默认值

    1. 利用解构传参,参数设置默认值   //show({ name = 'lucy', age = 22 } = {})  
                                //show([a = 0, b = 0])
    
    2. ES6 直接为参数添加默认值     //show(a = 0, b = 0)
    

    rest参数

    rest 参数: 接收不定参
    --
    1. rest 参数是一种方式(形参),rest参数可以重命名为其他参数 ...a
    2. rest 参数只能作为最后一个参数
    

    es6 对于对象的扩展**

    //1.对象的属性简写: 当对象的属性名和属性值(变量)名称一致,可省略赋值
    
    //2.对象的方法简写:
        let name = "jack";
        let age = 22;
        let obj = {
            name,
            age,
            walk: function () {
                console.log(this.name + " is walk");
            },
            say() {
                console.log(this.name + ` say`);
            }
        }
    

    es6 中箭头函数

    ES5 中的两种函数定义方法

    1. 函数式       //var fn = function(){}
    2. 声明式       //function show(){}
    

    ES6 中函数式声明方式被箭头函数( => )取代

    箭头函数:使用 => 定义函数
    
    1. 当函数没有参数时,()不能省略
    2. 当函数只有一个参数,且函数体是一句代码,且是返回语句, 参数的()可省略、函数体 {} 可省略、return 可省略、中间使用 => 连接
    3. 若函数体只有一句,且不是return 语句, 不能省略 {}
    4. 若函数体有多条语句,不能省略 {}
    5. 若函数有多个参数,不能省略()
    6. 若函数的返回值为对象,此时不能省略return

    使用箭头函数注意

    1. 箭头函数不适用于声明函数
    2. 箭头函数不适用于DOM事件
    3. 箭头函数不能作为构造函数(迭代器)
    4. 箭头函数内不能使用arguments
    5. 不能使用yield命令
    箭头函数this指向
    1. 箭头函数没有this,this是父级的
    2. 定义时候绑定,就是this是继承自父执行上下文中的this
    3. ES5中的this指调用者,ES6中的this指定义时候绑定

    字符串遍历

    let str = "hello";
        //1.for遍历
        for (let i = 0; i < str.length; i++) {
            console.log(i, str[i]);     //i 索引    数值类型
        }
        
        //2.数组->for->for in
        let arr = [1, 2, 3];
        for (let i in arr) {
            console.log(i, arr[i]);     //i 索引    字符串类型
        }
        
        //3.for... of
        for(let i of str){
            console.log(i);     //数据
        }
        
        //4.解构
        let [a, b, c, d ,e] = str;
        console.log(a, b, c, d ,e);
    

    ES6 新增字符串方法

    //字符串新增方法:
    方法                返回值          作用
    includes('str')     boolean         判断字符串中包含子串
    endWith('str')      boolean         判断字符串以"str"结尾
    startWith('str')    boolean         判断字符串以"str"开头
    repeat(n)           重复拼接自身      重复n次输出字符串 repeat + repeat
    
    //补全字符串长度的方法 
    padStart(length, s);        字符串开头补全
    endStart(length, s);        字符串末尾补全
    

    es6 模板字符串

    es6的模板字符串为反引号

    • 支持换行
    • 模板中传变量${变量}
    let obj = {
            name: 'jack',
            age: 20
        };
    
    console.log(`名称:${obj.name},年龄:${obj.age}`);  //名称:jack,年龄:20
    

    es6 的Set结构

    set结构 此结构中元素是唯一的,不能重复

    使用new Set()实例化
    
    方法:返回值是set可以连缀
      add(val)           加元素
      delete(val)        删元素
      has(val)           判断是否包含元素     boolean
      clear()            删除所有数据
        
        
    属性:
      size    元素个数
        
    
    set结构的遍历:
      1. for  of  遍历set
      2. for  of  遍历keys()
      3. for  of  遍历values()
      4. for  of  遍历对象实体 entries
      5. forEach遍历 set
      6. 使用扩展运算符 和 解构  将set结构转为数组
    
    // for of 遍历数据
        for (let i of set) {
            console.log(i);     //1  2  5  3
        }
       
        // 遍历 keys    等于遍历set
        for (let i of set.keys()) {
            console.log(i);
        }
        //遍历values
        for (let i of set.values()) {
            console.log(i);
        }
        //遍历对象实体 entries
        for (let i of set.entries()) {
            console.log(i[0]);
        }
        
        //解构的方式遍历对象实体
        for (let [k, v] of set.entries()) {
            console.log(k, v);
        }
        // for  each遍历 set
        set.forEach(i => {
            console.log(i);
        })
    

    es6 Map结构

    Map 结构 由于对象的属性只能接受字符串类型,所有产生了Map结构,优化对象结构, Map的Key能为任何属性

    使用new Map()实例化
    
    方法:返回值是Map实例可以连缀
        set(key,val)        加元素
        get(key)            取元素
        has(key)            判断是否包含元素     boolean
        clear()             删除所有数据
        
        // 1.添加数据 set()
        map.set('name', 'jack').set('age', 22).set(0,100);
        console.log(map);
        // 2.获取数据 get()
        console.log(map.get(0));        //100
        console.log(map.get('name'))    //jack
        // 3.判断存在数据 has()
        console.log(map.has(0));        //true
        // 4.删除数据 delete()
        map.delete(0);
        console.log(map);       //Map(2) {"name" => "jack", "age" => 22}
        // 5.清空数据 clear()
        map.clear();
        console.log(map);       //Map(0) {}
    

    Map结构规则

    //1. map 支持数组作为构造函数的参数,但必须是二维数组
    // let arr = [1, 2, 3, 4, 5];  //Iterator value 1 is not an entry object
    let arr = [['name', 'jack'], ['age', 23]];
    let map = new Map(arr);
    console.log(map);   //Map(4) {"name" => "jack", "age" => 23}
    
    // 2.key 不能重复,val可以重复, key如果重复会将原来的值覆盖
    map.set('name','tom');
    map.set('hob','sing');
    console.log(map);   //Map(5) {"name" => "tom", "age" => 23, "hob" => "sing"}
    

    Map的遍历

    • let of 遍历map
    • forEach 遍历 map
    • let of 遍历map.keys
    • let of 遍历map.values
    • let of 遍历map.entries
    • let of 遍历 map.entries + 解构
    // 1.let of 遍历map
        for (let i of map) {
            console.log(i[0], i[1]);
        }
       
        // 2.foreach 遍历 map
        map.forEach((v, k) => {
            console.log(k, v);
        })
      
        // 3.let of 遍历map.keys
        for (let k of map.keys()) {
            console.log(k, map.get(k));
        }
        
        // 4.let of 遍历map.values
        for (let v of map.values()) {
            console.log(v);
        }
        
        // 5.let of 遍历map.entries
        for (let i of map.entries()) {
            console.log(i[0], i[1]);
        }
        
        // 6.let of 遍历 map.entries + 解构
        for (let [k, v] of map.entries()) {
            console.log(k, v);
        }
    

    es6 set与map类型转换

    Set 和 数组
        1.set -> 数组
            方式1. Array.from();
            方式2. 遍历set然后push
            方式3. 扩展运算符
        2.数组 -> set
            方式1. new Set(arr);
        
    
    
    Map  对象  string
        1.map -> 对象 -> String
            方式1. forEach遍历Map -> 对象 -> JSON.stringify
        2.String -> 对象 -> map
            方式1. JSON.parse -> 对象 -> for...in 遍历对象 -> Map.add()
    

    Set 和 数组之间

    let set = new Set();
    set.add(1).add(2).add(3).add(2);
    // 1.Array.from();
    var arr = Array.from(set);
    console.log(arr);
    
    // 2.遍历set然后push
    var arr  = [];
    set.forEach(i=>{
        arr.push(i);
    });
    console.log(arr);
    
    // 3.扩展运算符
    var arr = [...set];
    console.log(arr);
    

    map、对象和字符串之间

    let map = new Map();
    map.set('name', 'jack').set('age', 22).set('tel', 151);
    
    // 1.map -> 对象 -> String
    var obj = {};
    map.forEach((v,k)=>{
        obj[k] = v;
    })
    console.log(obj);
    var str = JSON.stringify(obj);
    console.log(str);
    
    // 2.String -> 对象 -> map
    var obj1 = JSON.parse(str);
    var map1 = new Map();
    for(let i in obj1){
        map1.set(i,obj1[i]);
    }
    console.log(map1);
    

    rest 和 扩展运算符区别

    rest参数,出现在函数参数位置 离散数据 -> 数组

    function fn(...rest) {
        console.log(rest);
    }
    fn(100, 110, 120);    //(3) [100, 110, 120]
    

    ⚠️**注意: **... 扩展 运算符出现在非参数位置 **

    let arr = [1, 2, 3, 4, 5];
    console.log(...arr);    //1 2 3 4 5  
    
    function fn1() {
        console.log(arguments);     //Arguments(3) [2, 3, 4]
        console.log(...arguments);  //2 3 4
    }
    fn1(2,3,4);
    
    • 数组 -> 离散的数据
    • 拆分伪数组: NodeList HTMLCollection arguments...

    ES6 面向对象

    class 类、模板
    1. 构造器:当类被实例化时,自动执行构造器
    2. 每个类必须至少一个构造器,若没有,系统自动添加一个无参构造器
    3. 构造函数,不能主动调用
    
    
    set 和 get 设置和获取属性
    1. get 不能传递参数
    2. 只有当有set方法时才可以写get方法,同时出现
    
    
    静态方法:
    1. 类自身的方法,不用实例化即可调用
    2. 不会被实例继承,直接通过类来调用
    
    
    静态属性:
    1. 类名.属性名 = 值;
    
    
    extends 实现继承
    1. 继承是单向的
    2. 被继承的类属于父类,基类,也称超类
    3. 静态方法可以被子类继承
    4. 继承属性super()必须放在构造器第一句
    5. 一个父类可以有多个子类,一个子类只有一个父类
    
    
    注意:
    1. 父类可调用自己的成员方法
    2. 父类可以调自己的静态方法
    3. 父类不能调子类的成员方法
    4. 子类的实例可以调父类成员方法
    5. 子类的实例不能调父类静态方法
    6. 子类可以调父类静态方法
    
    class Person {
      static name = "Ken";
      constructor(uname, uage) {
        this.uname = uname;
        this.uage = uage;
      }
    
      //成员方法
      walk() {
        console.log(`${this.uname}正在奔跑!`);
      }
    
      // 静态方法:类自身的方法
      static cry() {
        console.log('人生下来就会哭!');
      }
    }
    
    // 静态属性
    Person.living = 'earth';
    
    
    //学生类继承Person类
    class Student extends Person {
      constructor(sname, sage, sno) {
        super(sname, sage);  //此句必须在构造器第一句
        this.sno = sno;
      }
      // 成员方法
      study() {
        console.log(`${this.sname}在学习呢!`);
      }
    
      //set 访问器 控制属性的设置
      set sage(age) { this._age=age}
      // get 访问器,获取属性
      get sage() { return this._age }
    }
    //创建类的实例   类的实例化
    var stu = new Student('王飒', 23, '001');
    stu.sage = 25
    console.log(stu.sage);
    

    JS中的异常处理

    try..catch
    try..finally
    try...catch..finally
    

    ES6 Promise 解决回调地狱

    promise:为了解决异步编程中的回调地狱而产生 Promise的实例需要接收一个函数作为参数 该函数又需要接收两个函数数作为参数 resolve 函数 reject 函数

    promise 的三种状态 pending 进行中 fullfilled 已成功 resolved 成功 执行resolve函数 rejected 已失败 rejected 失败 执行reject函数

    then方法 参数一:是resolve函数的实现 参数二:是reject函数的实现

    then方法返回值的是一个新的Promise实例 ⚠️注意,不是原来那个Promise实例 若前一个回调函数返回的是一个Promise对象(即有异步操作)时 后一个回调函数,会等待该Promise对象的状态发生变化,才会被调用

    promise的异常处理

    1. 建议总是使用catch方法。
    2. Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。
    3. Promise 的状态一旦改变,就永久保持该状态,不会再变了。
    4. catch方法返回的还是一个 Promise 对象
    5. catch和reject同时出现时,只执行reject

    多个异步操作

    // 加载图片函数
    function loadPic(id, src, sec) {
        return new Promise((resolve, reject) => {
            let oImg = new Image();
            oImg.onload = function () {
                resolve(oImg);
            }
            oImg.onerror = function () {
                reject(`编号为${id}的任务失败`);
            }
            // oImg.src = src;
            setTimeout(() => {
                oImg.src = src;
            }, sec);   //延迟加载函数
        })
    }
    let s1 = "远程图片";
    let s2 = "远程图片";
    let p1 = loadPic('001', s1, 1000);
    let p2 = loadPic('002', s2, 100);
    // Promise.all 方法
    // 当所有图片都加载完在执行后续动作,有一张失败都不执行then
    let p = Promise.all([p1, p2]);  //all返回新的promise对象
    p.then(data=>{
        console.log(data,'加载成功');
        document.body.append(data[0],data[1]);
    }).catch(err=>{
        console.log(err);
    }).finally(()=>{
        console.log('不论成功与否,我都执行');
    }); 
    // Promise.race 方法
    // 注:
    //  1.只要有一张图片加载完成,就执行then的resolve实现
    //  2.如果先加载的图片有失败的情况,后续图片就不加载,直接执行catch 或 reject
    let p = Promise.race([p1, p2]);
    p.then(data => {
        console.log(data);      //只返回最先加载成功的那个
        document.body.append(data);    //由于设置了延迟,所以第二个先加载完成
    }).catch(err => {
        console.log(err);
    })
    

    ES模块导入规则

    容易出错的地方

    1. 页面不基于服务器运行,会出现跨域的错误
    origin 'null' has been blocked by CORS policy: Cross origin requests are only
    
    1. 使用模块化时,页面不加type = "module" 会出现语法错误

    app.js:1 Uncaught SyntaxError: Unexpected token {

    <script src="./module/app.js" type="module"></script>
    
    1. import导入模块时不添加 .js 的后缀名会报找不到module错误

    GET xxx net::ERR_ABORTED 404 (Not Found)

    import { Student } from './Student.js';
    

    导出方式

    • 定义时导出
    • 批量导出
    • 导出重命名(不建议)
    • 默认导出
    // 1.定义时导出
    export let uname = '李四';
    
    export function showStudentName() {
      console.log(uname);
    }
    
    export class SomeAnimalInfo {
      constructor(type, age) {
        this.type = type;
        this.age = age;
      }
      showInfo() {
        console.log(`物种:${this.type},年龄:${this.age}`);
      }
    }
    
    
    
    // 2.批量导出
    const PI = 3.1415926;
    const DBNAME = 'Local';
        ... ...
    
    export { PI, DBNAME };
    
    
    
    // 3.默认导出 - 工具类
    export default class {
      static log(msg) {
        let now = new Date();
        console.log(`${now.toLocaleString()}    ${msg}`);
      }
    
      static setCookie() {
    
      }
            ... ...
    }
    

    导入方式

    • 导入重命名
    • 导入整个模块
    • 导入默认模块
    //1.导入重命名  as语法
    import { num, showStudentName as showName } from './all.js';
    
    // 2.导入整个模块   需要使用as重命名,接收的是一个对象
    import * as cons from './const.js';
    
    // 3.导入默认模块   需要起名,名字包含导出内容
    import Tool from './tools.js';
    

    es7 语法

    async await转化es5

    async function asyncFN() {
      var getSyncFnResult = await syncFn()
      console.log(getSyncFnResult);
    }
    
    function syncFn() {
      return "这是syncFn()的结果";
    }
    
    asyncFN()
    

    转成es5后的代码:

    function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
      try {
        var info = gen[key](arg); //相当于 步骤标点1-fn['next']("这是syncFn()的结果")
        var value = info.value;
      } catch (error) {
        reject(error);
        return;
      }
      if (info.done) {
        resolve(value);
      } else {
        Promise.resolve(value).then(_next, _throw);
      }
    }
    
    function _asyncToGenerator(fn) {
      //其实步骤标点1-fn=function* () {
      //   var getSyncFnResult = yield syncFn();
      //   console.log(getSyncFnResult);
      // }
      return function () {
        var self = this,
          args = arguments;
        return new Promise(function (resolve, reject) {
          var gen = fn.apply(self, args);
          function _next(value) {
            console.log("value", value);
    
            asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
          }
          function _throw(err) {
            asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
          }
          _next(undefined);
        });
      };
    }
    
    function asyncFN() {
      return _asyncFN.apply(this, arguments);
    }
    
    function _asyncFN() {
      _asyncFN = _asyncToGenerator(function* () {
        var getSyncFnResult = yield "这是syncFn()的结果";
        // var getSyncFnResult = yield syncFn();
        console.log(getSyncFnResult);
      });
    
      return _asyncFN.apply(this, arguments);
    }
    
    // function syncFn() {
    //   return "这是syncFn()的结果";
    // }
    
    asyncFN();
    

    ES5 ES6 ES7

    参考文献


    起源地下载网 » ES5 ES6 ES7

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元