之前分享过模块化,也提到了ES6新增的module。JavaScript一直没有模块体系,css都有@import。ES6标准实现了模块化功能,完全可以取代那些模块化规范,成为浏览器和服务器的通用方法。
有了module,我们不需要UMD模块格式,将来服务器和浏览器都会支持 ES6 模块格式。目前各种工具库都实现了。将来浏览器的新 API 就能用模块格式提供,不再必须做成全局变量或者navigator对象()的属性。不再需要对象作为命名空间(比如Math对象),未来这些功能可以通过模块提供。
ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict"。严格模式之前也分享过了,就不多说了。
模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。
需要注意的是,export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系,export语句输出的接口,与其对应的值是动态绑定关系:
export var a = 1;
var b = 2;
export {b}
export function fn() {}
function ex() {}
export {ex}
export b//报错
export ex//报错
export和import命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错。
使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块。import命令输入的变量都是只读的,因为它的本质是输入接口。也就是说,不允许在加载模块的脚本里面,改写接口,否则报错。
import命令具有提升效果,会提升到整个模块的头部,首先执行。import是静态执行,所以不能使用表达式和变量。import语句会执行所加载的模块,如果多次重复执行同一句import语句,那么只会执行一次。只要是加载一个模块的都只执行一次。
使用export default的时候:
function fn() {}
export {fn as default}等同于export default fn;
这时候export default后面不能跟变量声明语句:
export default var a = 1;是错误的。
同样的,直接导出值却正确了:
expprt default 1是正确的。
Export和import可以复合使用,foo和bar实际上并没有被导入当前模块,只是相当于对外转发了这两个接口:
export { a } from ‘./b’
可以用来改名或者整体输出。
模块是可以继承的:
export * from ‘a’;
表示输出a模块的所有属性和方法,会忽略a模块的default方法,然后可以把自定义的属性和方法都输出。
const声明的常量只在当前代码块有效,使用export就能跨模块使用。要注意,import和export命令只能在模块的顶层,不能在代码块之中,不管是if还是函数中,都会报错。
Import不能动态加载,require可以,想要实现取代require,就有提案引入import函数完成动态加载,返回一个promise对象。且import函数可以用在任何地方,非模块脚本也可以,是运行时执行。只要运行了就加载指定模块。Import()函数跟require只有一个同步和异步的区别。Import函数适用于按需加载、条件加载、动态模块路径等。然后就像使用promise对象一样,参数就是模块内容。
转载于:https://juejin.im/post/5d09ce7de51d45776031b00d