乐趣区

关于前端:Module理解及使用

ES6的模块化设计思维是动态化,也就是说,在编译的时候确定模块的依赖关系,以及输入输出入的变量。而 CommonJSAMD模块都是在运行时确定的。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、evalarguments不能被从新赋值
10、arguments 不会主动反映函数参数的变动
11、不能应用arguments.callee
12、不能应用arguments.caller
13、禁止this 指向全局对象
14、不能应用fn.callerfn.arguments获取函数调用的堆栈
15、减少了保留字(比方protectedstaticinterface


export 和 import 命令

模块次要有 exportimport形成,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 哟

退出移动版