ECMAScript 6 之Module

1. 概述

ES6 之前,模块加载方案主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。
ES6 在语言标准的层面上,实现了模块功能,ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。

2. 严格模式

ES6中模块自动采用严格模式,关于严格模式,请参考:严格模式

3. export 命令

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

一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。下面是一个例子:

// filter.js
// 将0、1 类型 week 转成汉字,如 1001101 转成 “日,三,四,六”
export function weekFormat(str) {
  if (typeof str !== 'string' || str === '') return ''
  const week = str.trim().split('')

  return ['日', '一', '二', '三', '四', '五', '六']
    .filter((item, index) => {
      return week[index] === '1'
    })
    .join(',')
}

上面代码是filter.js文件的内容,定义了一个星期转换函数weekFormat。ES6中,该文件就是一个模块,使用export命令对外输出了函数weekFormat

export命令还有一种写法,如下:

// filter.js
// 将0、1 类型 week 转成汉字,如 1001101 转成 “日,三,四,六”
function weekFormat(str) {
  if (typeof str !== 'string' || str === '') return ''
  const week = str.trim().split('')

  return ['日', '一', '二', '三', '四', '五', '六']
    .filter((item, index) => {
      return week[index] === '1'
    })
    .join(',')
}

export { weekFormat }

上面代码在export命令后面,使用大括号({})指定所要输出的一组变量。这种写法与上面的写法是等价的,但是更加清晰,一目了然。

通常情况下,export输出的变量就是本来的名字,但是可以使用as关键字重命名。

function f1() {
	...
}

export { f1 as getName}

export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。

export 1; // 报错

var m = 1;
export m; // 报错

正确写法如下:

export var m = 1;

// 或
var n = 1;
export { n }

注意:

  • export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。
  • export命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错。

4. import 命令

使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块。

// another.js
// 加载模块
import { weekFormat } from './filter.js'

// 使用模块
var util = {
	weekFormat 
}

import命令接受一对大括号({}),里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块对外接口的名称相同。

import命令也支持使用as关键字,将输入的变量重命名。

import { weekFormat as a } from './filter.js'

import命令输入的变量都是只读的,因为它的本质是输入接口。即不允许在加载模块的脚本里面,改写接口。

import {  a } from './xxx.js'

a = {} // Syntax Error : 'a' is read-only;

如果a是一个对象,改写a的属性是允许的。

import {  a } from './xxx.js'

a.propertyName = ... 

上面改写对象a的属性是合法的。

import命令具有提升效果,会提升到整个模块的头部,首先执行。

// 使用模块
var a = {
	weekFormat 
}

// 加载模块
import { weekFormat } from './filter.js'

上面例子中,先试用要加载的模块,再通过import命令加载要使用的模块,是可以的,因为import命令具有提升效果。

import命令是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构。

// 报错
import { 'week' + 'Format' } from './filter.js'

import后面的from指定模块文件的位置,可以是相对路径,也可以是绝对路径.js后缀可以省略。如果只是模块名,不带有路径,那么必须有配置文件,告诉 JavaScript 引擎该模块的位置。
在这里插入图片描述

5. export default 命令

export default命令,为模块指定默认输出。

// a.js
export default function (x, y) {
	return x + y
}

上面例子是一个模块文件a.js,通过export default命令指定了它的默认输出是一个函数。

其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。

import add from './a.js'

上面例子的import命令,可以用任意名称指向a.js输出的方法,但是,此时import命令后面,不使用大括号

export default命令也可以用在非匿名函数上。

// b.js
export default function add(x, y) {
	return x + y;
}

//或者
function add(x, y) {
	return x + y;
}

export default add;

上面例子中,函数add的函数名add只在模块内有效,在模块外部是无效的,加载的时候视同匿名函数。

下面是exportexport default命令的简单比较。

// export default 命令
export default function sum() {...}  // 输出

import sum from 'sum' // 输入

// export 命令
export function sum() {...} // 输出

import { sum } from 'sum' // 输入

本质上,export default命令就是输出一个叫做default的变量或方法,下面写法是有效的。

function add(x, y) {
  return x * y;
}

export {add as default};
// 等价于
export default add;

export default命令后面不能跟变量声明语句。

// 正确
export var a = 1;

// 正确
var a = 1;
export default a;

// 错误
export default var a = 1;

上面例子中,最后一种写法不允许,因为export default a的含义是将变量a的值赋给变量default

export default命令的本质是将后面的值,赋给default变量,下面写法是正确的。

// 错误
export 12;

// 正确
export default 12;

6. export 与 import 的复合写法

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

export { foo, bar } from 'my_module';

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

模块的接口改名可以采用复合写法。

export { foo as my_foo, bar as my_bar } from 'my_module';

默认接口可以采用复合写法。

export { default }  from 'my_module'

具名接口改为默认接口的写法如下。

export { foo as default } from 'my_module'

// 等价于
import { foo } from 'my_module'
export default foo;

默认接口改为具名接口写法如下:

export { default as foo } from 'my_module'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值