ES6
的模块化设计思维是动态化,也就是说,在编译的时候确定模块的依赖关系,以及输入输出入的变量。而CommonJS
和AMD
模块都是在运行时确定的。ES6
的模块不是对象,而是通过export
显示指定输入的代码,再通过import
命令输出。
// 模块输出import { start,address } from 'util'
下面的模块输出加载了两个办法,即便util
模块内有其它办法也不会加载,只会加载下面引入的两个办法,这种加载称为“编译时加载
”或动态加载
。
须要留神的是,ES6
的模块主动采取严格模式,不论头部有没有加上"use strict"
都会开启严格模式。严格模式的限度如下:
1、变量必须先申明再应用
2、函数参数不能有同名属性,否则报错
3、不能应用with
语句
4、不能对只读属性赋值,否则报错
5、不能应用前缀 0
示意八进制数,否则报错
6、不能删除不可删除的属性,否则报错
7、不能删除变量delete prop
,会报错,只能删除属性delete global[prop]
8、eval
不会在它的外层作用域引入变量
9、eval
和arguments
不能被从新赋值
10、arguments
不会主动反映函数参数的变动
11、不能应用arguments.callee
12、不能应用arguments.caller
13、禁止this
指向全局对象
14、不能应用fn.caller
和fn.arguments
获取函数调用的堆栈
15、减少了保留字(比方protected
、static
和interface
)
export和import命令
模块次要有export
和import
形成,export
规定模块对外的接口,import
用于输出模块提供的性能。
模块导出
// util模块// 类型function type(a){ return typeof a}// 计算function sum(a,b) { return a * b }// 判断是否为数组function isArray(a) { return a instanceof Array}export { type,sum } // 按需导出
模块导入
import { type,sum } from './util'let num = sum(10,5)console.log(num) // 50
下面两种形式是可选的形式导出的,也就是说,import
导入模块的时候,只会加载export
导出的办法,其它的办法不会被import
加载,并且import
引入util
模块能够按需引入,引入本人须要的模块即可,其它未引入的模块也不会加载,这也就是动态加载的益处。
除了export { xxx,xxx }
的按需导出外,ES6
还提供了export default
的默认导出,默认导出的办法,在import
导入的时候,不须要跟导出名始终,能够自定义名称接管导出的办法。
// util模块// 计算function sum(a,b) { return a * b }// 判断是否为数组function isArray(a) { return a instanceof Array}export default sum // 默认导出
import aaa from './util' // 导入时名字能够自定义let num = aaa(10,5)console.log(num) // 50
其实这个default
就是一个叫做default
的变量,这个变量能够被任意命名,在import
导入的时候,取任何名称都能够匹配上default
导出的办法。
按需和默认导出export { xxx,xxx }
和export default
默认导出能够同时应用
// util模块function type(a){ return typeof a}function sum(a,b) { return a * b }function isArray(a) { return a instanceof Array}export { type,sum }export default isArray
// 导入import { type,sum }from './util' import aaa from './util'
模块的整体加载
下面的导出办法都是加载模块内对应的办法,模块的整体加载要应用*
,也就是加载全副,语法如下
import * as util from './util';// 在页面中应用let num = util.sum(10,5)console.log(num) // 50
这种写法是将模块整体加载,用*
指定一个对象,所有输入的值都加载在这个对象下面。通过该对象.办法名来获取对应办法。
须要留神的是,ES6
的模块是动态剖析
的,不容许对模块进行扭转
,所以上面写法是不容许的:
util.sum = 'hello' // 报错util.sum = function () {} // 报错
模块继承
模块之间也是能够继承的,假如A
模块继承了B
模块
// A模块function sum(a,b) { return a * b }function isArray(a) { return a instanceof Array}export * from 'B' // 输入B模块的所有属性和办法,疏忽模块内的default办法export { sum } export default isArray
export *
命令会疏忽B
模块的default
办法,因为A
模块外部有本人的default
办法。
模块的重命名
// util模块export { sum as s }// 页面import { s } from './util' // 引入命名后的办法
模块按需引入import()
失常状况下import
是须要在页面顶层引入的,并且import
的引入执行的优先级是最高的,例如:
let s = sum(10,5)import { sum } from './util'
下面这种写法是容许的,程序会执行import
的引入,而后再执行let s = sum(10,5)
,但这种写法会默认导入模块,并且是在顶层导入。es6
提供了动静导入性能:import()
,当程序执行到该语句的时候才会导入,并且是同步执行,import()
返回的是一个Promise
,所以能够应用then
办法和async-await
。
Promise写法
import('./util.js').then(el=>{ console.log(el.t(100)); // number console.log(el.sum(10,5)); // 50})
async-await写法
async function getImport(){ let { sum } = await import('./util.js') console.log(sum(2,8));}getImport() // 16
也能够通过解构的形式获取
import('../module/import.js').then(({sum})=>{ console.log(sum(20,5)); // 100})
如果模块是default
默认导出,其实default
就是一个键名
import('../module/import.js').then((e)=>{ console.log(e.default([1,2,3])); // true})
default
也能够通过具名的模式导入(取别名)
import('../module/import.js').then(({default : isA})=>{ console.log(isA([1,2,3])); // true})
import.meta
在应用一个模块时,有时候须要晓得该模块自身的信息(比方模块的门路),import
命令新增了一个元属性import.meta
,能够返回以后模块的信息。
留神:import.meta
只能在模块内应用,在模块外应用会报错
// util模块function sum(a,b) { return a * b }function getMeta(){ return import.meta // 获取以后模块的元信息}export { sum,getMeta }
// console.log(import.meta); // import.meta只能在模块内应用,在模块内部应用会报错import('./util.js').then(el=>{ console.log(el.getMeta()); // {url: 'http://127.0.0.1:5500/module/import.js', resolve: ƒ}})
案例源码:https://gitee.com/wang_fan_w/es6-science-institute
如果感觉这篇文章对你有帮忙,欢送点亮一下star哟