深刻探究ES6之模塊系統

在上一篇《前端模塊化,AMD和CMD的區別總結》中,介紹了commonJS規範下衍生出來的AMD和CMD。多年來,前端的js代碼大都是以這種方式組織起來(再早連這個都沒有。。。),可是從語言設計自己的層面上講,官方一直沒有設計出javascript的模塊系統,直到。。。ES6的正式發佈!javascript

能夠說ES6的正式發佈(討論了十年)是前端界翹首以盼衆望所歸的事,它是javascript被建立以來最重要的更新之一。而其中最重要的就是JS模塊化的定義,從原生語法上支持了導入與導出模塊,咱們終於再也不須要使用一些庫(Requirejs、Seajs等)來模仿模塊化了。前端

本文不想過多介紹如何使用ES6模塊的語法(好比import和export的規範),由於網絡上關於這方面的介紹已經不少了,如今來講點不太常被說起可是對理解有很重要的東西。java

「模塊」是自動運行在嚴格模式下而且沒有辦法退出運行的JavaScript代碼。模塊有三個比較顯著的特性:git

一、在模塊頂部建立的變量不會自動被添加到全局做用域(好比windows下),訪問模塊的變量必須經過導出的方式。

二、在模塊頂部this的值是undefined。

三、模塊不支持HTML的代碼註釋。

以上也是ES6模塊區別於傳統模塊系統很重要的三點,並且ES6模塊系統與傳統模塊系統更顯著的一個區別是:github

四、ES6的模塊系統是靜態解析的

舉例:windows

if(Math.random()){
    import name from './example.js'   // 拋出錯誤
}
-------------------------------------------------
let name = 'js'
if(Math.random()){
    export {name}   // 拋出錯誤
}
複製代碼

import和export不能在條件語句或任何動態方式中使用,緣由是要讓JavaScript引擎靜態地肯定哪些模塊能夠導出。
若是使用過RequireJS或者SeaJS的開發者應該深有體會,它們可沒有這樣的限制。 因爲ES6模塊的靜態性,致使了一個怪異甚至讓人困惑之處,先看一個例子:bash

//a.js
let name = 'ajs';
let setName = fuction(newName) {
    name = newName;
}
export {name, setName}

//b.js
import {name, setName} from './a.js';
console.log(name)   // 'ajs'
name = 'bjs'    // 拋出錯誤
setName('cjs')
console.log(name)   // 'cjs'
複製代碼

b.js只是簡單的引用了a.js中的值,而不能改變a.js中的值,當調用setName('cjs')時會回到a.js中去執行,並將其中的name設置爲'cjs'。這說明ES6模塊輸出的是值的引用,與CommonJS(輸出的是值的拷貝)徹底不一樣。網絡

至於將ES6模塊系統設計成靜態的緣由,你們能夠參考這篇文章Static module resolution。其中原理較爲深奧,我的認爲能夠不求甚解。dom

PS:動態import(不是ES6的內容)

凡事有利就有弊,靜態性的模塊系統在帶來一系列好處的同時,也限制了開發者對於項目靈活性的掌控。好比在某些條件語句或是用戶點擊觸發的操做裏面,動態(或者說按需)導入模塊的要求就變得很迫切。不過還好,如今動態導入的提案已經存在於TC39第三階段了。模塊化

你能夠這樣使用:

if(Math.random()){
    import('./example.js').then((M)=>{
        let Mod = M.default
        // TODO
    }) 
}
或者
if(Math.random()){
    import('./example.js').then(({setName})=>{
        setName('Dynamic')
        // TODO
    }) 
}
甚至是這樣
const locale = 'en';
import(`./utils_${locale}.js`).then(
  (utils)=>{
    console.log('utils', utils);
    utils.default();
  }
);
複製代碼

·你能夠在延遲加載、條件加載和用戶操做的情景下使用動態導入
·動態import()能夠在腳本的任何地方使用
·import()可以傳遞字符串,你能夠根據你的需求構造匹配符

歡迎你們積極留言指出問題及不足,我會及時修改文章內容,咱們也能夠一塊兒探討一些技術問題,道理越講越清楚。

相關文章
相關標籤/搜索