只是搬遷本身以前丟在簡書的文字寫於初學es6時因此語句不通(雖然並沒有價值)git
是隻是export,因此......import忽略es6
本篇代碼運行環境爲
{"presets": [ "es2015","stage-2" ] }
這只是做爲參考,且只是運行環境,不推薦在學習ES6時將代碼所有轉譯爲ES5,ES6轉化後的代碼只能告訴你結果,相比較而言,緣由或是理由的價值超過結果,學習ES6,不僅僅要知道代碼運行的結果,最重要的目的是,知其因此然,瞭解一個行爲爲何會這麼發生,行爲的背後又是什麼,這纔是學習者所須要追尋的github
文章參考: You-Dont-Know-JS ECMAScript 6 入門 ES6規範15.2.3.2 Static Semantics: BoundNamesbash
首先登場的就是 export , 這是一個主要關鍵詞,基本用法是放置在一個"聲明"以前,或一組由{}
語法(注意,此處的{}語法與對象無關)
包裹的即將被導出的"標識符"以前app
//export 放置在"聲明"以前
export var a = 1, b = 2, c = 3
export let a = 1
export const a = 1
export let { a } = { a: 1 }
export var foo = function() {}
export function foo() {}
//export 放置在一組"標識符"以前
var a = 1, b = 2
export { a, b }
//等同於
export var a = 1
export var b = 2
複製代碼
以上例子有一個明確的共同點,export 後面沒有出現「表達式」。實際上,單獨的export 是對變量標識符(指針位置)的綁定,並期許未來會把對應的標識符(指針)導出。函數
將「變量標識符」導出,這樣的描述容易產生混淆,考慮下面的代碼學習
var a = 1
export { a }
a = 3
//等同於
export var a = 1
a = 3
複製代碼
當這個模塊被導出後,若是賦值發生,那麼已被導出的值也將被更新,不管導出發生在任何階段。進一步的說,在被導入時的值是可有可無的。這些綁定是實時的連接,因此惟一重要的是當你訪問這個綁定時它當前的值是什麼。ui
參考規範15.2.3.2
ExportDeclaration : export VariableStatement
1. Return the BoundNames of VariableStatement.
ExportDeclaration : export Declaration
1. Return the BoundNames of Declaration.
能夠看到export 的導出是明確的
複製代碼
另外「標識符」一詞引用於The above rule means that each ReferencedBindings of ExportClause is treated as an IdentifierReference.主要是詞窮,而且由於模塊導出與賦值是不一樣的,在進行導出時,實質上是導出了一個單向綁定的
(不容許在導入的一方進行改變)
變量的引用,是的,更準確的說應該是對於變量這個容器的引用,模塊導出並不關心變量的值。spa
在進行導出的時候,可使用別名,關鍵詞 as指針
var a = 1
export { a as b }
//將 a 重命名爲 b
複製代碼
"在一個模塊中,使用import命令的時候,用戶須要知道所要加載的變量名或函數名,不然沒法加載。可是,用戶確定但願快速上手,未必願意閱讀文檔,去了解模塊有哪些屬性和方法。"
"爲了給用戶提供方便,讓他們不用閱讀文檔就能加載模塊,就要用到export default命令,爲模塊指定默認輸出。"
上述兩句直接摘自ECMAScript 6 入門,主要是感受是很恰當的描述,若是加以變更反倒多此一舉了,固然還不夠全面,因此對default進來如下的補充
每一個模塊定義只能有一個default,它是惟一的,每一個被導出的模塊只包含一個default元素,因此export default命令在模塊內只被容許使用一次。
本質上export default就是輸出一個叫作default的默認標識符。等同於,將export default 以後的內容以賦值的形式添加到default元素上。
var a = 1
export default a
//等同於
export default 1
//導出的是那表達式在那一刻的值的綁定,不是 標識符a的綁定(export.default = 表達式)
複製代碼
export default 有許多微妙的細節,使人困擾的(不是結果,而是行爲)。請思考下面的代碼。
//m2.js
1.
function foo() {}
export default foo
foo = 'change'
2.
export default (function foo() {})
foo = 'change'
3.
function foo() {}
export { foo as default }
foo = 'change'
//因爲上文已經描述過,default接近於標識符,因此,能夠直接重命名foo做爲default導出。
4.
export default function foo() {}
foo = 'change'
//另外一模塊
import * as all from 'm2.js'
console.log(all)
複製代碼
你的大腦可以清晰的知道每一個模塊即將會發生的事情嗎?若是不能那麼請繼續閱讀,若是能,那麼也但願你繼續閱讀,重溫複習這一片斷。下面讓我複製代碼,描述並解釋每一模塊的行爲。 ######模塊1.
function foo() {}
//聲明foo
export default foo
//將foo賦值給default元素(注意,此時foo是表達式)
foo = 'change'
//結果
{ default: [Function: foo] }
複製代碼
export default 導出的是那一個函數表達式在那一刻的值的綁定,不是 標識符foo的綁定。換句話說,export default ..接收一個表達式。若是你稍後在你的模塊內部賦給foo一個不一樣的值,這個模塊導入將依然表示本來被導出的函數,而不是那個新的值。
規範裏定義了export default 表達式的導出相關行爲export default AssignmentExpression
ExportDeclaration : export default AssignmentExpression ; 1.Return «"default"». 簡單解釋下,就是將表達式的值賦予default,而後返回default ######模塊2.
export default (function foo() {})
將(..)賦值給default 元素(注意,()是表達式)
foo = 'change'
//結果
ReferenceError: foo is not defined
export default !function foo() {}
!等運算符能夠包裝一個函數使它做爲一個表達式返回值
複製代碼
export default (function foo(){}),export default後面的是函數表達式,並非函數聲明定義,因此它對應的規範與模塊1相同,導出的ExportedBindings也就是一個«"default"»。
這裏之因此報錯是由於函數表達式只會返回函數自己做爲值,並不會在外部做用域定義同名變量,因此下面的foo = 'change'找不到foo這個定義。
######模塊3.
function foo() {}
export { foo as default }
foo = 'change'
//結果
{ default: 'change' }
複製代碼
ExportDeclaration : export Declaration 1.Return the BoundNames of Declaration. 行爲與 export '標識符‘相同,因此引用的規範相同,惟一須要理解的是default是能夠被賦值
######模塊4.
export default function foo() {}
//一個函數聲明出現了!
foo = 'change'
//結果
{ default: 'change' }
複製代碼
function foo..部分是一個函數表達式,可是對於模塊內部做用域來講,它被視爲一個函數聲明,由於名稱foo被綁定在模塊的頂層做用域
export default 函數聲明定義在規範中定義的行爲,對應的是export default HoistableDeclaration. ExportDeclaration : export default HoistableDeclaration 1.Let declarationNames be the BoundNames of HoistableDeclaration. 2.If declarationNames does not include the element "default", append "default" to declarationNames. 3.Return declarationNames.
能夠看到按照規範若是將要導出的聲明沒有包含元素default,那麼就進行賦值(規範概念),最後返回的是一個當前綁定的標識符,與前面的表達式時狀態不一樣。因此結果可以看到,導出值被更新了。
原標題爲ES6 Module 詳解,而後發現本身並無真正理解Module這部分因而停筆,回去看書了,實際意義上本文是爲了總結知識
初學ES6,文章有誤請指點,文內部分用詞不許確也請諒解,雖然引用了規範,可是並無能力進行解讀,慚愧。
文章參考: You-Dont-Know-JS ECMAScript 6 入門 ES6規範15.2.3.2 Static Semantics: BoundNames