• JS高级之ES6+模块化


    十四、es6内容

    可参考阮一峰的ECMAScript 6 入门

    14.1 数组API、正则API、字符串API

    14.2 模板字符串

    • 模板字符串的基本用法
    var s1 = `abc`
    
    • 模板字符串的优势:
    var obj={ name:"",age:5 };
    var s1 ="我叫:"+obj.name+",今年:"+obj.age+"岁。"
    

    14.3 解构赋值

    14.3.1 对象的解构赋值

    var obj={name:"张三",age:18}
    
    var {name,age}=obj; 
    //生成2个变量,
    //  name值来自于obj.name、
    //  age值来自于obj.age
    
    var {name:title}=obj;
    //生成一个变量:title,值来自于obj.name
    

    14.3.2 函数参数的解构赋值

    function f1(obj){
        console.log(obj.age);
        console.log(obj.height)
    }
    //等价于
    function f1({ age,height }){
        console.log(age);
        console.log(height)
    }
    f1({age:5,height:180})
    

    14.3.3 补充:属性的简写

    var a = 3 ; 
    var c = 10;
    var b = { a,c } ;   
    //b对象有一个a属性,a属性的值,来自于a变量  ,
    //还有一个c属性,c属性的值来自于c变量
    console.log(b)
    

    14.4 函数的扩展

    14.4.1 rest参数

    使用背景:es6的
    优点:arguments是伪数组,而rest参数是真数组

    function fn(...args){
        console.log(args);  //数组:[1,2,3,4,5]
    }
    fn(1,2,3,4,5)
    

    14.4.2 箭头函数

    场景:用于替换匿名函数
    基本用法:

    //匿名函数
    div.onclick=function(){
        console.log("你好")
    }
    //箭头函数
    div.onclick=()=>{
        console.log("你好")
    }
    

    有一个参数的箭头函数

    var fn=(a)=>{
        console.log("abc");
    }
    //等价于:
    var fn=a=>{
        console.log("abc");
    }
    

    有2个及更多参数的箭头函数

    var f=(a,b,c)=>{
        console.log("abc")
    }
    

    箭头函数和普通匿名函数有哪些不同?

    • 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
    • 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
    • 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
    • (不常用)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
      • generator函数现在经常用async替代

    14.5 对象的扩展

    • Object.assign:实现拷贝继承
    • 对象扩展运算符
    var obj1={ age:5,gender:"男" }
    var obj2={ ...obj1 }
    var obj3={ ...obj1 , age:10 }
    

    14.6 Promise

    为什么要有promise:解决回调地狱的问题

    14.6.1 回调地狱:

    //跟以前的if条件地狱很像
    // if(){
    //     if(){
    //         if(){
    //         }
    //     }
    // }
    
    $.get("/getUser",function(res){
        $.get("/getUserDetail",function(){
            $.get("/getCart",function(){
                $.get("/getBooks",function(){
                    //...
                })
            })
        })
    })
    //node开发:读取文件;开个服务器、接收一个请求、请求路径、访问数据库
    

    14.6.2 Promise函数基本用法

    var promise=new Promise((resolve,reject)=>{
        //b 把需要执行的异步操作放在这里
        $.get("/getUser",res=>{
            //获取数据的异步操作已经执行完毕了,等待下一步的执行,通过执行resolve函数,告诉外界你可以执行下一步操作了
            //c、
            resolve(res)
            //而执行的下一步操作,其实就是写在then的回调函数中的
        })
    })
    //a、
    promise.then(res=>{
        //d、执行后续的操作
        console.log(res);
    })
    

    14.6.3 Promise函数实现多层回调

    new Promise((resolve,reject)=>{
        $.get("/getUser",res=>{
            resolve(res)
        })
    }).then(res=>{
        //用户基本信息
        return new Promise(resolve=>{
            $.get("/getUserDetail",res=>{
                resolve(res)
            })
        })
    }).then(res=>{
        //用户详情
        return new Promise(resolve=>{
            $.get("/getCart",res=>{
                resolve(res)
            })
        })
    }).then(res=>{
        //购物车信息
    })
    

    14.6.4 Promise函数错误处理

    方式一

    new Promise((resolve,reject)=>{
        $.ajax({
            url:"/getUser",
            type:"GET",
            success:res=>{
                resolve(res);
            },
            error:res=>{
                reject(res)
            }
        })
    }).then(resSuccess=>{
        //成功的返回值
    },resError=>{
        //失败的返回值
    })
    

    方式二:

    new Promise((resolve,reject)=>{
        $.ajax({
            url:"/getUser",
            type:"GET",
            success:res=>{
                resolve(res);
            },
            error:res=>{
                reject(res)
            }
        })
    }).then(resSuccess=>{
        //成功的返回值
    }).catch(resError=>{
        //失败的返回值
    })
    

    14.7 async

    async其实是一个promise的语法糖

    async function get(){
        console.log('开始执行');
        var res = await timer()
        console.log('执行结束:',res);
    }
    function timer(){
        return new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve("你好");
            },1000)
        })
    }
    get();
    
    • await可以执行异步操作,但是await必须在async函数内执行
    • await操作可以有返回值,这个返回值表示promise操作成功的返回值
    • 如果await里面执行的异步操作发生了reject,或者发生了错误,那么只能使用try…catch语法来进行错误处理

    14.8 generator

    Generator是ES6的新特性,通过yield关键字,可以让函数的执行流挂起,那么便为改变执行流程提供了可能。

    14.9 class

    14.9.1 定义一个类

    class Person {
        constructor(name) {
            this.name=name;
        }
    }
    //相当于:
    function Person(name){
        this.name=name;
    }
    

    14.9.2 添加实例方法

    class Person {
        constructor(name,age) {
            this.name=name;
            this.age=age;
        }
        //定义方法
        say() {
            console.log("大家好,我叫:"+this.name+",今年:"+this.age+"岁");
        }
        travel(){
            console.log("坐着飞机去巴厘岛");
        }
    }
    

    14.9.3 添加静态方法

    • 静态成员:静态属性、静态方法
    • 静态属性:通过类本身来访问:Person.maxAge
    • 静态方法:通过类本身来访问的一个方法:Person.born();
    class Animal {
        constructor(){
    
        }
        static born(){
            console.log("小呆萌出生了")
        }
    }
    //访问静态方法
    Animal.born();
    

    14.9.4 类的继承

    //父类
    class Person {
        constructor(name){
            this.name=name;
        }
    }
    //Student类继承自Person类
    class Student extends Person {
        //构造方法
        constructor(name,grade){
            //规定:必须调用父类构造方法,如果不调用就会报错
            super(name);    
            //调用父类构造方法,从而给子类的实例添加了name属性
    
            this.grade=grade;
        }
    }
    
    [1,3,5].map(function(value,index){})
    [1,3,5].map((value,index)=>{})
    //以前变量和字符串拼接,现在用模板字符串
    

    14.10 module

    14.10.1 浏览器调试

    本地调试,会受浏览器同源策略的影响,需要开启web服务才能打开

    <script type="module">
        //导入模块
    </script>
    

    14.10.2 基本用法

    导出模块:

    //common.js
    export default { name:"abc" }
    

    导入模块:(

    //b.js
    import common from "common.js"
    console.log( common.name ) //"abc"
    

    14.10.3 模块有多个导出

    //person.js
    export const jim = { country :"France" }
    export const tony = { color:"gray" }
    //默认的导出
    export default { name:"abc" }
    
    //index.js
    import person , { jim , tony } from "person.js"
    
    //person:{ name:"abc" }
    //jim:{ country :"France" }
    //tony:{ color:"gray" }
    

    14.10.4 模块导入导出取别名

    //person.js
    export const tony = { color:"gray" }
    export { tony as Tony }
    
    //index.js
    import { Tony } from "person.js"
    import { Tony as man} from "person.js"
    
    console.log(man)    //{ color:"gray" }
    

    十五、模块化

    15.1 非模块化的弊端

    • 代码杂乱无章,没有条理性,不便于维护,不便于复用
    • 很多代码重复、逻辑重复
    • 全局变量污染
    • 不方便保护私有数据(闭包)

    15.2 基本实现:闭包的自调用函数

    //日期控件
    var DatePicker = (function(){
        return {
            init(){}
        }
    })();
    
    //Header
    //  tabbar
    //  login
    
    //Content
    //  sidebar
    //  table
    
    //Footer
    var KTV=(function(){
        return {
            pay(){},
            xiaofei(){}
        }
    })()
    

    15.3 AMD模块化 -->requireJS

    • AMD:async module define:异步模块定义
    • AMD其实就是requireJS实现的模块化解决方案

    15.4 其他模块化解决方案:

    • CommonJS:Node中使用的模块化解决方案
    • CMD(common module define):seajs中提出来的模块化解决方案
      • 其实CMD可以认为是CommonJS的前端实现
      • seajs由阿里的(玉帛)编写
      • seajs在2,3年前比较火,从去年开始已经停止更新
        • vue 、angular、react已经集成了各自的模块化
        • es6模块化
        • webpack也有模块化的解决方案

    15.5 AMD和CMD的不同之处

    • amd需要依赖前置,cmd需要依赖就近
    • 导入导出方式不同:
      • amd通过define定义,return导出;
      • cmd通过不需要定义,只需要最后通过module.exports、exports导出

    15.6 requireJS —— AMD规范

    requireJS中文网

    15.6.1 基本用法

    //1、通过script标签导入requirejs源文件
    //2、编写模块文件,基本格式如下:
    //home.js
    define([],function(){
        console.log('home模块');
    })
    //user.js
    define([],function(){
        console.log('user模块');
    })
    //3、首页调用模块:
    require(["home","product.js"],function(){ })
    

    15.6.2 入口文件

    15.6.3 配置

    require.config({
        baseUrl:'js',
        paths:{
        	'jquery':'jquery.min.js',
        }
        
    })
    

    15.6.4 定义模块的返回值(返回值相当于模块的入口)

    //user.js:
    define([],function(){
        return {
            init(){},
            addUser(){}
        }
    })
    //首页:运行时加载
    require(["cart"],function(cart){
        cart.init();
        cart.addUser();
    })
    

    注意:一般在导入模块的时候,需要将有返回值的模块[前面]导入,无返回值的模块[后面]导入

    15.6.5 案例——模块依赖子模块

    //userAdd.js
    define([],function(){
        return {
            init(){
                console.log("添加用户");
            }
        }
    })
    
    //userEdit.js
    define([],function(){
        return {
            init(){
                console.log("编辑用户");
            }
        }
    })
        
    //user.js   define(["userAdd","userEdit"],function(userAdd,userEdit){
        return {
            init(){
                console.log("用户初始化");
            },
            add(){
                userAdd.init();
            },
            edit(){
                userEdit.init();
            }
        }
    })
    
    //首页:
    require(["user"],function(user){
        user.init();
        user.add();
        user.edit();
    })
    

    15.6.7 检测第三方库是否支持AMD规范

    if ( typeof define === "function" && define.amd ) {
        define([], function() {
            return jQuery;
        } );
    }
    

    类似的还有:echarts

    15.6.8 常用的模块、文件夹路径的配置

    一般用于配置第三方模块,比如jquery、bootstrap、zepto等等

    require.config(
        paths:{
            jquery:"js/lib/jquery-1.11.min",
            zepto:"js/lib/zepto.min",
            bootstrap:"assets/bootstrap/js/bootstrap.min"
        }
    )
    define(["jquery","zepto"],function($,$$){})
    require(["jquery","bootstrap"],function($){})
    

    15.6.9 插件

    • 插件列表:https://github.com/requirejs/requirejs/wiki/Plugins
    • i18n 国际化
    • text 加载文件(.html文件。。。)

    15.6.10 requirejs解决循环依赖

    • a已经依赖了b
    • b中先添加require模块的依赖,然后再添加a的依赖,但是并不要去通过回调函数的形参获取返回值
      • define(["require","a"],function(require){})
      • 在需要执行a模块代码的时候,require("a")()

    15.6.11 requirejs和vuejs浅显的比较

    • requirejs是一个库
      • 功能:只是一种模块化的解决方案
    • vue是一个框架
      功能:
      • 1、不仅仅是模块化的解决方案
      • 2、减少了DOM的操作(–>jquery的功能)

    15.6.12 node中的模块化

    • require(“http”).createServer()
    • require(“fs”).readFile()
    • require(“common/type”).doSth()

    15.6.13 前端路由的意义

    • 1、通过路由将各个功能从url上面就分辨出来了
      • /user/list
      • /user/3
      • /user/edit/3
    • 2、路由还可以进行前进、后退等导航操作

    15.6.14 前端路由的实现方式

    • 1、监听window对象的hashchange事件
      • hash值:通过location.hash获取,获取的值以#开头
      • 也可以通过location.hash来设置hash值,当然设置的新hash也应该以#开头
    • 2、history对象:popState/pushState
  • 相关阅读:
    【Spring】的【bean】管理(XML配置文件)【Bean实例化的三种方式】
    【Spring】---【IOC入门案例】
    【Spring】---【IOC】
    DOM4J解析文件
    Hibernate API的使用(Query、Criteria、SQLQuery对象)
    Hibernate一级缓冲
    搭建Hibernate环境
    Python之路【第十六篇】:Django【基础篇】
    Python之路【第十五篇】:Web框架
    Python之路【第十四篇】:AngularJS --暂无内容-待更新
  • 原文地址:https://www.cnblogs.com/daozhangblog/p/12446349.html
Copyright © 2020-2023  润新知