模块化的代码实现
let module = (function () {
const moduleList = {}
function define(name, modules, action) {
modules.map((module, index) => {
modules[index] = moduleList[module]
})
moduleList[name] = action.apply(null, modules)
}
return {define}
})()
module.define('cal', [], function () {
return {
max(arr, key) {
return arr.sort((a, b) => b[key] - a[key])[0]
}
}
})
module.define('lessen', ['cal'], function (cal) {
let lessens = [
{name: 'js', price: 100},
{name: 'php', price: 200}
]
console.log(cal.max(lessens, 'price'))
})
模块的使用
// cal.js 文件
let max = '这是一个 cal 模块中的 max 函数'
export {
max
}
<!-- index.html 文件 -->
<script type="module">
import {max} from './cal.js'
console.log(max)
</script>
1、script 标签要加上 type="module" 属性,才能解析 js 模块相关内容,同样,以 src 方式引入 js 文件的方式也需要加这个属性。
2、引入模块文件时的相对路劲的 './' 不能少。
3、加上 type="module" 属性后,这一段 js 代码就会延迟解析,原因是解析器需要加载完后续所有模块,获得并处理好所有模块的依赖关系后,才会继续解析(包括 html 解析)。
4、默认开启严格模式。
模块的作用域
<script type="module">
var a = 'a'
</script>
<script type="module">
var b = 'b'
console.log(a) // a is not defined
</script>
模块拥有独立的作用域
模块的具名导出
// cal.js 文件
export let abc = 'abc...'
export function func() {
console.log('func...')
}
export class User {
static show() {
console.log('User.show...')
}
}
<script type="module">
import {abc, func, User} from './cal.js'
console.log(abc)
func()
User.show()
</script>
等同于放在同一个对象中导出:
// cal.js
let abc = 'abc...'
function func() {
console.log('func...')
}
class User {
static show() {
console.log('User.show...')
}
}
export {abc, func, User}
模块的批量导入(不推荐)
上述例子还可以这样导入:
<script type="module">
import * as cal from './cal.js'
console.log(cal.abc)
cal.func()
cal.User.show()
</script>
但是不推荐这样导入,原因是一,没有具名导入那么一目了然,看不到到底导入了哪些接口;二、* 号表示全部导入,会把不需要的接口也一起导入。
默认导出 export default
当模块内只有一个接口需要导出时,可以使用默认导出:export default
// cal.js 文件
export default class User {
static show() {
console.log('User.show...')
}
}
<script type="module">
import User from './cal.js' // 注意:这里的 User 不需要大括号,且不一定非得用 User,可以用任意变量接收导入的接口
User.show()
</script>
混合导入导出
当模块内既有具名导出,又有默认导出时,叫做混合导出
// cal.js 文件
export let abc = 'abc'
export default class User {
static show() {
console.log('User.show...')
}
}
<script type="module">
import User, {abc} from './cal.js' // User 代表默认导入,{abc} 代表具名导入
console.log(abc)
User.show()
</script>
模块的按需加载 import
// cal.js 文件
export let abc = 'abc...'
export function func() {
console.log('func...')
}
export class User {
static show() {
console.log('User.show...')
}
}
<script type="module">
if (true) {
import("./cal.js").then(({func, User}) => {
func()
User.show()
})
}
</script>
import() 会返回一个 Promise 对象,用 then 函数接收。