第4章 ES6模块化

目标

  • 模块化系统演进
  • ES6模块化实现

模块化概述

在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。

为什么使用模块化?
技术的诞生是为了解决某个问题,模块化也是。在js模块化诞生之前,开发者面临很多问题:随着前端的发展,web技术日趋成熟,js功能越来越多,代码量也越来越大。之前一个项目通常各个页面公用一个js,但是js逐渐拆分,项目中引入的js越来越多:

模块化系统演进

上面的js引入造成了问题:

1)全局变量污染:各个文件的变量都是挂载到window对象上,污染全局变量。
2)变量重名:不同文件中的变量如果重名,后面的会覆盖前面的,造成程序运行错误。
3)文件依赖顺序:多个文件之间存在依赖关系,需要保证一定加载顺序问题严重。
4)在大型项目中各种资源难以管理,长期积累的问题导致代码库混乱不堪

后来出来了CommonJS AMD CMD UMD(建议了解)
https://www.jianshu.com/p/c33c659b2a1e

ES6模块化实现

1、ES6模块化概述
ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。

2、ES6模块化特点
1)静态加载模块,效率比CommonJS 模块的加载方式高
2)ES6 模块是编译时加载,使得静态分析成为可能进一步拓宽 JavaScript 的语法,比如引入宏(macro)和类型检验(type system)这些只能靠静态分析实现的功能。
3)不再需要UMD模块格式了,将来服务器和浏览器都会支持 ES6 模块格式。目前,通过各种工具库,其实已经做到了这一点
4)将来浏览器的新 API 就能用模块格式提供,不再必须做成全局变量或者navigator对象的属性。
5)不再需要对象作为命名空间(比如Math对象),未来这些功能可以通过模块提供。
6)支持严格模式

3、export和import命令
模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能
在ES6中每一个模块即是一个文件,在文件中定义的变量,函数,对象在外部是无法获取的。如果你希望外部可以读取模块当中的内容,就必须使用export来对其进行暴露(输出)。
然后在需要引用上述变量、函数、对象的文件里用import的形式进行引入:
a-export--->
b-import <--
1)变量模块化
** 输出两种方式(自选)**
param01_export.js

export let userName="wangqj";
export const PI=3.1415926;

简写形式

    let userName="wangqj";
    const PI=3.1415926;
    export {userName,PI};

** 输入(注意type="module"):**
param01-import.html

    

运行结果:

第4章 ES6模块化_第1张图片
image

上面代码的js文件,保存了一些基本信息。ES6 将其视为一个模块,里面用export命令对外部输出了几个变量。

2)函数模块化
输出fun_export.js :
第一种写法:

//fun_export.js  
export function cheng(x, y) {
    return x * y;
}
export function jia(x, y) {
    return x + y;
}
export function jian(x, y) {
    return x - y;
}

第二种 简写形式:

function cheng(x, y) {
    return x * y;
}
function jia(x, y) {
    return x + y;
}
function jian(x, y) {
    return x - y;
}
export {cheng,jia,jian};

第三种 export时也可以用as定义别名,重命名后,import时需要用新名引入:

function cheng(x, y) {
    return x * y;
}
function jia(x, y) {
    return x + y;
}
function jian(x, y) {
    return x - y;
}
export {cheng,jia as add,jian};

输入fun_import.html:

    

第4章 ES6模块化_第2张图片
image

3)对象模块化
输出:

    export class person{
        constructor(username,password) {
            this.username=username;
            this.password=password;
        }

        toString(){
            return this.username+' '+this.password;
        }
    }

输入:

    

第4章 ES6模块化_第3张图片
image

其他需要说明的地方:
1)import 时可以定义别名,用别名来引用,重命名后,v2可以用不同的名字输出两次。

    import { lastName as surname } from './profile.js';

2)import命令具有提升效果,会提升到整个模块的头部,首先执行

    foo();
    import { foo } from ‘./my_module.js';

上面的代码不会报错,因为import的执行早于foo的调用。这种行为的本质是,import命令是编译阶段执行的,在代码运行之前。
3)import是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构
4)import语句是 Singleton 模式 无论代码import了几次,都只执行一次

4、模块的整体加载
除了指定加载某个输出值,还可以使用整体加载,即用星号(*)指定一个对象,所有输出值都加载在这个对象上面。

整体加载.js

    let username="wang.qj";
    let password="123456";
    function login(username,password){
        return "登录成功";
    }
    export{username,password,login} ;

整体加载 .html

    

5、export default 命令(掌握)
使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。
为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。

default01.js

const str = "hello es6";
export default str;//此处不用加花括号

default01.html

    

注意:
1)原本直接export str外部是无法识别的,加上default就可以了.但是一个文件内最多只能有一个export default。 其实此处相当于为str变量值起了一个系统默认的变量名default,自然default只能有一个值,所以一个文件内不能有多个export default。
本质上,default01.js文件的export default输出一个叫做default的变量,然后系统允许你为它取任意名字。所以可以为import的模块起任何变量名,且不需要用大括号
2)书写时注意:两侧都不需要{}了

再来两个例子:

export default function

default02.js

    export default function (x,y){
        return x+y;
    }

default02.html

    

export default class##

default03.js

    export default class person{
        constructor(username,password) {
            this.username=username;
            this.password=password;
        }

        toString(){
            return this.username+' '+this.password;
        }
    }

default03.html

    

再来一个

    export default{
        username:"wang.qj",
        password:"123456",
        login:(username,password)=>{
            return "success"+username;
        }
    }


    
    
    



你可能感兴趣的:(第4章 ES6模块化)