模块化 Module
在 ES6 之前, 社区制定了一些模块加载方案, 最主要的有 CommonJS 和 AMD 两种. 前者用于服务器, 后者用于浏览器. ES6 在语言标准的层面上, 实现了模块功能, 而且实现得相当简单, 完全可以取代 CommonJS 和 AMD 规范, 成为浏览器和服务器通用的模块解决方案.
ES6 的模块化的基本规则或特点:
每一个模块只加载一次, 每一个 JS 只执行一次, 如果下次再去加载同目录下同文件, 直接从内存中读取. 一个模块就是一个单例, 或者说就是一个对象;
每一个模块内声明的变量都是局部变量, 不会污染全局作用域;
模块内部的变量或者函数可以通过 export 导出;
一个模块可以导入别的模块.
模块功能主要由两个命令构成: export 和 import.export 命令用于规定模块的对外接口, import 命令用于输入其他模块提供的功能.
- // ES6 模块
- import {
- stat, exists, readFile
- } from 'fs';
export 命令
一个模块就是一个独立的文件. 该文件内部的所有变量, 外部无法获取. 如果你希望外部能够读取模块内部的某个变量, 就必须使用 export 关键字输出该变量.
使用命名导出
使用命名导出语法如下, 可导出变量, 函数, class(类)
- export {
- name1, name2, ..., nameN
- };
- export {
- variable1 as name1, variable2 as name2, ..., nameN
- };
- export let name1, name2, ..., nameN; // also var
- export let name1 = ..., name2 = ..., ..., nameN; // also var, const
- export function FunctionName() {
- ...
- }
- export class ClassName {
- ...
- }
导出数据, 变量前面加上 export 关键字
- export var firstName = 'Michael';
- export let lastName = 'Jackson';
- export const year = 1958;
- // 上面的等价于下面的写法, 以下这种是常见写法
- var firstName = 'Michael';
- let lastName = 'Jackson';
- const year = 1958;
- export {
- firstName, lastName, year
- }
导出函数, 函数前面加上 export 关键字
- function multiply(x, y) {
- return x * y;
- }
- export multiply;
- // 上面的等价于下面的写法
- export function multiply(x, y) {
- return x * y;
- };
导出类, 类前面加上 export 关键字
- export class Point {
- constructor(x, y) {
- this.x = x;
- this.y = y;
- }
- toString() {
- return '(' + this.x + ',' + this.y + ')';
- }
- }
使用默认导出
因为 export default 命令其实只是输出一个叫做 default 的变量, 所以它后面不能跟变量声明语句, 使用默认导出语法如下,
- export default expression;
- export default function (...) {
- ...
- } // also class, function*
- export default function name1(...) {
- ...
- } // also class, function*
- export {
- name1 as default, ...
- };
默认导出(函数)
export default function() {}
默认导出(类)
export default class {}
export default 和 export 区别
export 与 export default 均可用于导出常量, 函数, 文件, 模块等, 但 export default 后不可直接跟 var,let,const, 也就是其后面不能直接跟变量声明语句;
- // 正确
- export var a = 1;
- // 正确
- var a = 1;
- export default a; // 将变量 a 的值赋给变量 default
- // 错误
- export default var a = 1;
因为 export default 命令的本质是将后面的值, 赋给 default 变量, 所以可以直接将一个值写在 export default 之后, 但 export 却不能.
- // 正确
- export default 42;
- // 报错(因为没有指定对外的接口)
- export 42;
- // 正确
- var m = 42;
- export {
- m
- };
可以在其它文件或模块中通过 import+(常量 | 函数 | 文件 | 模块)名的方式, 将其导入, 以便能够对其进行使用;
使用 export default 命令, 为模块指定默认输出, 这样就不需要知道所要加载模块的变量名, 导入时可以任意为其取名字. 但使用 export 时, 在导入时必须与被导入模块对外接口的名称相同;
在一个文件或模块中, export,import 可以有多个, export default 仅有一个;
通过 export 方式导出, 在导入时要加{ },export default 则不需要;
- // 使用 export
- export const str = "blablabla~";
- export function log(sth) {
- return sth;
- }
- // 对应的导入方式:
- import { str, log } from 'a'; // 也可以分开写两次, 导入的时候带花括号
- // 使用 export default
- const str = "blablabla~";
- export default str;
- // 对应的导入方式:
- import str from 'a'; // 导入的时候没有花括号
模块的整体加载
除了指定加载某个输出值, 还可以使用整体加载, 即用星号 (*) 指定一个对象, 所有输出值都加载在这个对象上面.
- // circle.JS
- export function area(radius) {
- return Math.PI * radius * radius;
- }
- export function circumference(radius) {
- return 2 * Math.PI * radius;
- }
现在, 加载这个模块.
- // main.JS
- import {
- area, circumference
- } from './circle';
- console.log('圆面积:' + area(4));
- console.log('圆周长:' + circumference(14));
上面写法是逐一指定要加载的方法, 整体加载的写法如下.
- import * as circle from './circle';
- console.log('圆面积:' + circle.area(4));
- console.log('圆周长:' + circle.circumference(14));
import 命令
使用 export 命令定义了模块的对外接口以后, 其他 JS 文件就可以通过 import 命令加载这个模块.
导入整个模块的内容
import * as myModule from '/modules/my-module.js';
导入单个导出
import {myExport} from '/modules/my-module.js';
导入多个导出
import {foo, bar} from '/modules/my-module.js';
导入带有别名的导出
import {reallyLongModuleExportName as shortName} from '/modules/my-module.js';
导入时重命名多个导出
- import {
- reallyLongModuleMemberName as shortName,
- anotherLongModuleName as short
- } from "my-module";
导入默认值
- // 直接导入默认值
- import myDefault from "my-module";
- // 与命名空间导入或命名导入一起使用
- import myDefault, * as myModule from "my-module";
- // 或者
- import myDefault, {
- foo, bar
- } from "my-module";
参考文章
- export | MDN
- import | MDN
来源: http://www.jianshu.com/p/6ea1a3a80d38