【深入淺出ES6】模組化Modules

Eric_zhang發表於2019-03-04

【深入淺出ES6】模組化Modules

模組的匯入匯出

  1. 匯出export
    export let a = 111 //匯出基本型別
    export function add(){} // 匯出類
    export class Rectangle{} // 匯出函式
    
    function multiply(num1, num2){
        return num1*num2
    }
    export { multiply }
    複製程式碼
  2. 匯入import
    import { num } from './example.js' //匯入單個模組
    import * as Example from './example.js' //匯入所有模組併合並在一個名稱空間物件上
    複製程式碼
    注:
    • 當程式碼執行到import匯入語句時,會根據引用的路徑,執行匯出模組的程式碼,也就是完成匯出模組的例項化,並且將該模組例項儲存在記憶體中,同一應用的任何模組引用此匯出模組時,都會複用已在記憶體中的模組例項,而不會重新進行匯出模組的例項化
    // 多次import同一模組,只在例項化一次模組,之後都會複用這個模組例項
    import {sum} from './example.js'
    import {multiply} from './example.js'
    import {add} from './example.js'
    複製程式碼
    • 匯入的常量是匯出變數的只讀引用
    import { num } from './example.js' // 不能給num重新賦值,同時當example.js中的num值變化時,這裡的num也會跟著變化
    num = 'Tom' //error報錯
    複製程式碼
  3. 重新命名匯入和匯出名稱
    function sum (num1, num2){
        return num1 + num2
    }
    // 匯出模組
    export {sum as add}
    
     // 引入模組
    import {add as sum } from './example.js'
    複製程式碼
  4. 匯出模組預設值
    //法一
    export default function add(){}
    //法二
    function add(){}
    export default add
    //法三
    function add(){}
    function multiply(){}
    export {add as default, multiply} //匯出多個,並設定預設匯出
    複製程式碼
  5. 匯入模組預設值
    import sum from './example.js' //不適用大括號{},名字也可以隨便取
    import sum ,{ multiply } from './example.js' // 既有預設值sum,也有非預設值,非預設值要放到{}中,並且名稱要和匯出模組的名稱保持一致
    //上面的寫法等價於下面的寫法
    import {default as sum, multiply} from './example.js'
    複製程式碼
  6. 匯入再匯出
    import { add } from './example.js'
    export { add }
    
    //合併到一句的寫法:
    export { add } from './example.js'
    //從example.js中匯入add,並命名為sum匯出
    export { add as sum } from './example.js'
    複製程式碼
  7. 無繫結的匯入(比如css檔案等,不需要明確指定引入的模組內容)
    import './style.css'
    複製程式碼

Web瀏覽器中模組執行的順序

新型瀏覽器針對script標籤增加type='module'的屬性,來支援模組化語法的資源引入

  1. 遇到<script type='module'> 的標籤時,會立即下載對應的js資源,下載完後會解析js,遇到import語句會取請求對應的資源
  2. 下載和解析<script type='module'> 資源的時候,並不會影響html接下來的解析
  3. 在html解析載入完成之前只會做下載和解析工作,不會執行js程式碼,執行js的順序會嚴格按照<script>顯式引入和import隱式引入的順序來依次執行

案例分析:

<script type='module' src='module1.js'></script>

<script type='module'>
    import {sum} from './example.js'
    let result = sum(1,2) 
</script>

<script type='module' src='module2.js'></script>
複製程式碼

正確的順序:

  1. 下載並解析module1.js
  2. 遞迴下載並解析在module1.js中使用import引入的資源
  3. 解析內聯模組
  4. 遞迴下載並解析內聯模組中使用import引入的資源example.js
  5. 下載並解析module2.js 在html解析完成之前,都不會有任何JS執行,當html解析完成之後,DOMContentLoaded觸發之前,開始執行js,執行js的順序如下:
  6. 遞迴執行module1.js中引入的資源(按照import的順序依次執行)
  7. 執行module1.js
  8. 遞迴執行內聯模組import的資源
  9. 執行內聯模組的程式碼
  10. 遞迴執行module2.js中引入的資源(按照import的順序依次執行)
  11. 執行module2.js

注意:<script type='module'></script>採取的就是defer屬性的方式,因此設不設定defer沒有任何影響;但是設定async屬性後,會按照async的模式,下載解析完,並且所有包含的import資源也都下載解析後按照引入順序立即執行js

【深入淺出ES6】模組化Modules

相關文章