ES6 学习笔记(17) Module 的语法

1. 概述


由于 ES6 模块是编译时加载,使得静态分析成为可能。有了它,就能进一步拓宽 JavaScript 的语法,比如引入宏(macro)和类型检验(type system)这些只能靠静态分析实现的功能。

除了静态加载带来的各种好处,ES6 模块还有以下好处。

不再需要UMD模块格式了,将来服务器和浏览器都会支持 ES6 模块格式。目前,通过各种工具库,其实已经做到了这一点。
将来浏览器的新 API 就能用模块格式提供,不再必须做成全局变量或者navigator对象的属性。
不再需要对象作为命名空间(比如Math对象),未来这些功能可以通过模块提供。

2. 严格模式


ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict";。
严格模式主要有以下限制。

变量必须声明后再使用
函数的参数不能有同名属性,否则报错
不能使用with语句
不能对只读属性赋值,否则报错
不能使用前缀0表示八进制数,否则报错
不能删除不可删除的属性,否则报错
不能删除变量delete prop,会报错,只能删除属性delete global[prop]
eval不会在它的外层作用域引入变量
evalarguments不能被重新赋值
arguments不会自动反映函数参数的变化
不能使用arguments.callee
不能使用arguments.caller
禁止this指向全局对象
不能使用fn.callerfn.arguments获取函数调用的堆栈
增加了保留字(比如protectedstaticinterface

3. export 命令


模块功能主要由两个命令构成:exportimportexport命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

  // 写法一
  export var m = 1;

  // 写法二
  var m = 1;
  export {m};

  // 写法三
  var n = 1;
  export {n as m};

最后,export命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错,下一节的import命令也是如此。这是因为处于条件代码块之中,就没法做静态优化了,违背了 ES6 模块的设计初衷。

4. import 命令


使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块。
最后,import语句会执行所加载的模块,因此可以有下面的写法。

  import { foo } from 'my_module';
  import { bar } from 'my_module';
  // 等同于
  import { foo, bar } from 'my_module';

5. 模块的整体加载


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

  // circle.js  导出模块

  export function area(radius) {
    return Math.PI * radius * radius;
  }

  export function circumference(radius) {
    return 2 * Math.PI * radius;
  }
  // 整体引入
  import * as circle from './circle';
  console.log('圆面积:' + circle.area(4));
  console.log('圆周长:' + circle.circumference(14));

6. export default 命令


为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。

  // export-default.js
  export default function foo() {
    console.log('foo');
  }

  // 或者写成

  function foo() {
    console.log('foo');
  }

  export default foo;

如果想在一条import语句中,同时输入默认方法和其他接口,可以写成下面这样。

  import _, { each, each as forEach } from 'lodash';

7. export 与 import 的复合写法


如果在一个模块之中,先输入后输出同一个模块,import语句可以与export语句写在一起。

  export { foo, bar } from 'my_module';

  // 可以简单理解为
  import { foo, bar } from 'my_module';
  export { foo, bar };

模块的接口改名和整体输出,也可以采用这种写法。

  export { es6 as default } from './someModule';

  // 等同于
  import { es6 } from './someModule';
  export default es6;

8. 模块的继承


假设有一个circleplus模块,继承了circle模块。

  // circleplus.js

  export * from 'circle';
  export var e = 2.71828182846;
  export default function(x) {
    return Math.exp(x);
  }

9. 跨模块常量


本书介绍 const 命令的时候说过, const 声明的常量只在当前代码块有效。如果想设置跨模块的常量(即跨多个文件),或者说一个值要被多个模块共享,可以采用下面的写法。

  // constants.js 模块
  export const A = 1;
  export const B = 3;
  export const C = 4;

  // test1.js 模块
  import * as constants from './constants';
  console.log(constants.A); // 1
  console.log(constants.B); // 3

  // test2.js 模块
  import {A, B} from './constants';
  console.log(A); // 1
  console.log(B); // 3

10. import()


因此,有一个提案,建议引入import()函数,完成动态加载。
import()返回一个 Promise 对象。下面是一个例子。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • ES6模块不是对象,而是export命令显示指定输出的代码,输入时也采用静态命令的形式。 上面是从fs模块里加载3...
    竹天亮阅读 12,236评论 2 17
  • 以下内容是我在学习和研究ES6时,对ES6的特性、重点和注意事项的提取、精练和总结,可以做为ES6特性的字典;在本...
    科研者阅读 8,378评论 2 9
  • [TOC] 参考阮一峰的ECMAScript 6 入门参考深入浅出ES6 let和const let和const都...
    郭子web阅读 5,817评论 0 1
  • 模块通常是指编程语言所提供的代码组织机制,利用此机制可将程序拆解为独立且通用的代码单元。所谓模块化主要是解决代码分...
    MapleLeafFall阅读 4,910评论 0 0
  • 三国时期,魏国的势力强大后,曹操年迈已衰,眼下有两个他还看好的继承人,一个是曹丕,另一个就是曹植。 曹植天生就聪慧...
    接近真理阅读 5,418评论 2 4

友情链接更多精彩内容