一、module模式

       对于一个大型,复杂的项目,我们需要根据功能或类别,将程序拆成一个个独立的模块文件,然后依据每个模块之间的依赖和关联,组装成一个完整的可运行的程序,这种模式有利于清晰的架构设计,开发人员的相互协同,称之为module(模块)体系,java的import,Ruby的require等。

     很遗憾,在ES6前,js官方是没有这样的标准的。我们只能通过<script>标签引入一个js文件,与文件一起编译,无法做到模块化加载。

      尽管官方没有标准,但是无所不能的js社区早已未雨绸缪,出现了模块化加载方案,最主要的是CommonJS和AMD规范。

commonjs主要应用于服务器,实现同步加载,如nodejs。AMD规范应用于浏览器,如requirejs,为异步加载。同时还有CMD规范,为同步加载方案如阿里的seaJS。

二、export与import

ES6的模块体系是由export与import两个命令构成,export是定义需要导出的模块对外接口,import定义需要导入的模块接口。

创建一个a.js,定义需要导出的属性和方法。

//a.js
//导出属性
export var name="tcy";
export var sex="mail";
//导出方法
export function printName(){
	 console.log("the name is:"+name);
}

同一个目录下,创建一个module.html,加载a.js模块,调用其中的属性和方法。

<script type="module">
    import {name,sex,printName} from "./a.js";
    console.log(name);//tcy
    console.log(sex);//mail
    printName();//the name is:tcy
 </script>

注意:1、script标签中,需要增加"type=module",否则执行报错。

          2、import对于待导入模块的属性和方法,需要用{}括起来。

为了结构更加清晰,更直观,推荐如下的方式,用{}将待导出的属性和方法列举出来。

//a.js
//导出属性
var name="tcy";
var sex="mail";
//导出方法
function printName(){
	 console.log("the name is:"+name);
}
//集中导出
export {name,sex,printName}

加载时,除了一一列出,还可以整体导入,用(*)表示一个对象,

<script type="module">
    import * as a from "./a.js";
    console.log(a.name);//tcy
    console.log(a.sex);//mail
    a.printName();//the name is:tcy
 </script>

import命令是发生编译阶段,即代码执行之前,所以下面这段代码是报错的

<script type="module">
    if(true){
      import * as a from "./a.js";//报错
    }
    console.log(a.name);//tcy
    console.log(a.sex);//mail
    a.printName();//the name is:tcy
 </script>

这样做的好处是提高运行的效率,但是无法做到动态加载。

import是静态执行的,也就是说不支持任何表达式和变量,如:

<script type="module">
    import {"a"+"b"} as a from "./a.js";//报错
    console.log(a.name);//tcy
    console.log(a.sex);//mail
    a.printName();//the name is:tcy
 </script>

三、export default

default表示的是默认接口,在import导入的时候可以忽略对象名字,任意命名。如:

//a.js
//导出属性
var a = 1;
export default a;

import导入该默认接口,注意:不要使用{},这个是与导入具名变量的区别。

import _ from "./a.js";
console.log(_);//1

有些同学可能注意到,在export导出是,我们做了一个赋值,那如果直接用export default var a=1,是否可以呢,大家可以试下,结果是报错了。原因是,default 本身就是个变量名,只能赋值给它,而不能再带一个变量。可以写成下面这种形成

export default 1;

既然是默认接口,所以只能是一个,其他的都只能具名导出。

//a.js
//导出默认属性
var name = "tcy";
export default name;
var sex="mail";
//导出方法
 function printName(){
	 console.log("the name is:"+name);
}
//具名导出
export {sex,printName}
<script type="module">
    import _,{sex,printName} from "./a.js";
    console.log(_);//tcy
    console.log(sex);//mail
    printName();//the name is:tcy
 </script>



四、总结

我们看到ES6的模块加载非常简单,其设计的思想就是尽量的静态化,后续会取代CommonJS和AMD的方案

上一篇:ES6系列教程第六篇--Class继承                                         下一篇:ES6系列教程第八篇--箭头函数详解