引言:由于两个JS文件之间相互使用必须通过一个html文件作为中介。ES6添加Module模块特为两个JS文件的直接引用。 |
一、Module的由来
ES6的Class只是面向对象编程的语法糖,升级了ES5的构造函数的原型链继承的写法,并没有解决模块化问题。Module 功能则是为了解决这个问题而提出的。
历史上,JavaScript一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如Ruby的require、Python的import,甚至连CSS都有@import,但是JavaScript没有任何这方面的支持,这对于开发大型的、复杂的项目形成了巨大障碍。
在ES6之前,社区制定了一些模块加载方案,最主要的有CommonJS和AMD两种。前者用于服务器,后者用于浏览器。ES6 在语言规格的层面上实现了模块功能,而且实现得相当简单,完全可以取代现有的CommonJS和AMD规范,成为浏览器和服务器通用的模块解决方案。
ES6模块的设计思想是尽量静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS和AMD模块都只能在运行时确定这些东西。比如,CommonJS模块就是对象,输人时必须查找对象属性。
let { state, exists, readFile } = require('fs');
以上代码的实质是整体加载fs模块(即加载fs的所有方法),然后在使用时用到3个方法。这种加载称为“运行时加载”。
ES6模块不是对象,而是通过export命令显式指定输出的代码,输人时也采用静态命令的形式。
import { stat, exists, readFile } from 'fs';
以上代码的实质是从fs模块加载3个方法,其他方法不加载。这种加载称为"编译时加载",即ES6可以在编译时就完成模块编译,效率要比CommonJS模块的加载方式高。
除了静态加载带来的各种好处,ES6 模块还有以下好处。
●不再需要UMD模块格式,将来服务器和浏览器都会支持ES6模块格式。目前,通过各种工具库其实已经做到了这一点。
●将来浏览器的新API可以用模块格式提供,不再需要做成全局变量或者navigator对象的属性。
●不再需要对象作为命名空间(比如Math对象), 未来这些功能可以通过模块提供。
二、严格模式
因为JS的语法规则确实比较随意,在一些大型项目中不太合适,所以官方提供了严格模式,在头部加上"use strict",ES6的模块自动采用严格模式。
严格模式主要有如下限制:
●变量必须声明后再使用。
●函数的参数不能有同名属性,否则报错。
●不能使用with语句。
●不能对只读属性赋值,否则报错。
●不能使用前缀0表示八进制数,否则报错。
●不能删除不可删除的属性,否则报错。
●不能删除变量 (delete prop)会报错,只能删除属性(delete gloabl [prop])。
●eval不会在其外层作用域引入变量。
●eval和arguments不能被重新赋值。
●arguments不会自动反映函数参数的变化。
●不能使用arguments.callee.
●不能使用arguments.caller.
●禁止this指向全局对象。
●不能使用fn.caller和fn.arguments获取函数调用的堆栈。
●增加了保留字(比如protected、static和interface)。
三、export命令
模块功能主要由两个命令构成: export 和import。export 命令用于规定模块的对外接口,import命令用于输人其他模块提供的功能。
一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。下面是一个JS文件,里面使用export命令输出了变量。
// profile.js export var firstName ='Michael'; export var LastName = 'Jackson' ; export var year = 1958;
上面的代码保存了用户信息。ES6将其视为一个模块,里面用export命令对外部输出了3个变量。 export的写法,除了像上面这样,还有另外一种。
// profile.js var firstName = 'Michael' ; var LastName = 'Jackson' ; var year = 1958; export {firstName,LastName,year};
暴露的接口,还可以设置别名。如下。
function v1() {} function v2() {} export { v1 as fun, v2 as ny, v2 as sun };
四、import命令
同样,import的写法如下。
import {firstname , lastname , year} from './profile';
同样,import也可以重命名。
import {firstname as a} from './profile';
【注意】import具有提升效果。只要不在代码块内书写,位置任意。
查看更多ES6教学文章:
参考文献
阮一峰 《ES6标准入门(第2版)》