ES6的模塊化設計思想是靜態化,也就是說,在編譯的時候確定模塊的依賴關係,以及輸出輸出入的變數。而CommonJS和AMD模塊都是在運行時確定的。ES6的模塊不是對象,而是通過export顯示指定輸出的代碼,再通過import命令輸入。 // 模塊輸入 import { start,address ...
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喲