摘要:當(dāng)我們學(xué)習(xí)的模塊化,就會(huì)發(fā)現(xiàn)它的發(fā)展深受的影響。嚴(yán)格模式在模塊系統(tǒng)中,嚴(yán)格模式是默認(rèn)開啟的。同樣的,模塊內(nèi)部的聲明只在模塊內(nèi)部有效。在中,我們使用導(dǎo)入內(nèi)容在模塊中,我們只需要為導(dǎo)入的綁定起一個(gè)名字我們也可以導(dǎo)入具名導(dǎo)出的內(nèi)容。
ES6 模塊系統(tǒng)
在 ES6 之前,我們已經(jīng)知道了 RequireJS,AngularJS 的依賴注入,以及 CommonJS,具體可以看筆者的上一篇文章《JS模塊化歷史簡(jiǎn)介》。當(dāng)我們學(xué)習(xí) ES6 的模塊化,就會(huì)發(fā)現(xiàn)它的發(fā)展深受 CommonJS 的影響。通過(guò)這篇文章,我們將看到 export 和 import 語(yǔ)句,以及 ES6 模塊是怎么與 CommonJS 模塊兼容的。
嚴(yán)格模式在 ES6 模塊系統(tǒng)中,嚴(yán)格模式是默認(rèn)開啟的。嚴(yán)格模式是語(yǔ)言從語(yǔ)法層面限制你使用一些不好的寫法,所以它更嚴(yán)格(==)。它也讓編譯器更好地處理代碼。下面是 MDN上關(guān)于嚴(yán)格模式的解釋:嚴(yán)格模式
變量必須顯式聲明
函數(shù)的形參必須有唯一的名稱(否則會(huì)報(bào)語(yǔ)法錯(cuò)誤)
不能使用with
給只讀的屬性賦值會(huì)報(bào)錯(cuò)
像 00840 這樣的八進(jìn)制數(shù)字會(huì)報(bào)語(yǔ)法錯(cuò)誤
試圖 delete 無(wú)法刪除的屬性會(huì)報(bào)錯(cuò)
delete prop 會(huì)報(bào)語(yǔ)法錯(cuò)誤,可以使用 delete global[prop]
eval 不會(huì)在所在的詞法作用域引入新的變量
eval 和 arguments 不能被改變或賦值
arguments 不會(huì)跟蹤方法的參數(shù)變化
arguments.callee 不再支持,會(huì)報(bào) TypeError
arguments.caller 不再支持,會(huì)報(bào) TypeError
傳入方法內(nèi)部的 this 不再被強(qiáng)制轉(zhuǎn)換成 Object
fn.caller 和fn.arguments 不再支持
保留關(guān)鍵字 protected,static ,interface 不能被綁定
即使在 ES6 中嚴(yán)格默認(rèn)是默認(rèn)開啟的,也推薦在每個(gè)模塊中都使用 use strict 關(guān)鍵字。
讓我們先來(lái)看下 export 關(guān)鍵字吧~
export在 CommonJS 中,導(dǎo)出模塊可以用 module.exports 。從下面的代碼可以看出,你可以導(dǎo)出任何值:
module.exports = 1 module.export = NaN module.exports = "foo" module.exports = { foo: "bar" } module.exports = ["foo", "bar"] module.exports = function foo () {}
像 CommonJS 模塊一樣,ES6 模塊也是暴露 API 的文件。同樣的,ES6 模塊內(nèi)部的聲明只在模塊內(nèi)部有效。這就意味著,某個(gè)模塊中的變量,如果沒有被導(dǎo)出,在其他模塊中就無(wú)法使用。
Exporting a Default Binding上面的 CommonJS 代碼如果用 ES6 語(yǔ)法寫起來(lái)也很相似,主要就是將 module.exports 替換為 export default
export default 1 export default NaN export default "foo" export default { foo: "bar" } export default ["foo", "bar"] export default function foo () {}
而與 CommonJS 不同的是,export 語(yǔ)句只能放在 ES6 模塊代碼的頂層,就算放在一個(gè)立即執(zhí)行的函數(shù)中也不行??上攵@種限制讓編譯器更容易解析 ES6 模塊,同時(shí)也讓避免了在方法中動(dòng)態(tài)導(dǎo)出這種不是很實(shí)用的騷操作。
function foo () { export default "bar" // SyntaxError } foo()
導(dǎo)出語(yǔ)法不是只有 export default,你也可以使用具名導(dǎo)出。
Named Exports在 CommonJS 中導(dǎo)出時(shí)也不是必須將 module.exports 賦值為一個(gè)對(duì)象,你可以直接改變它的屬性。
module.exports.foo = "bar" module.exports.baz = "ponyfoo"
好了,下面用 ES6 的寫法也很簡(jiǎn)單(原文說(shuō)了一堆不太重要就沒翻~):
export var foo = "bar" export var baz = "ponyfoo"
有一句話要始終牢記,我們導(dǎo)出的是綁定而不是值。
Bindings, Not Values在 ES6 模塊中重要的一個(gè)點(diǎn)是:導(dǎo)出的是綁定,而不是值或者引用。這就意味著你導(dǎo)出的變量foo 被綁定在了模塊上,它的值改變了,外部也能收到變化。盡管通常情況下不推薦在模塊加載后改變導(dǎo)出的值。
如果你有一個(gè) ./a 模塊,導(dǎo)出的 foo 將在 500ms 后從 bar 變?yōu)?baz:
export var foo = "bar" setTimeout(() => foo = "baz", 500)
除了默認(rèn)綁定和具名綁定,我們還可以導(dǎo)出一個(gè)列表的綁定。
Exporting Lists下面的代碼可以看到,ES6 模塊允許我們導(dǎo)出一個(gè)包含頂級(jí)成員的列表:
var foo = "ponyfoo" var bar = "baz" export { foo, bar }
如果你想改變其中變量的名字,可以用以下語(yǔ)法:
export { foo as ponyfoo }
同時(shí)也可以指定其中的某個(gè)為默認(rèn)導(dǎo)出:
export { foo as default, bar }
而通常的最佳實(shí)踐是只使用 export default,并且將其放在模塊的底部。
Best Practices and export如果同時(shí)使用命名導(dǎo)出,導(dǎo)出列表和默認(rèn)導(dǎo)出,很容易造成困擾,所以大部分情況下作者建議只使用 export default,并且將語(yǔ)句放在模塊文件的底部。你可以將要導(dǎo)出的對(duì)象叫作 api :
var api = { foo: "bar", baz: "ponyfoo" } export default api
這樣做有幾個(gè)好處:(原文比較啰嗦,下面提煉兩點(diǎn))
將導(dǎo)出的內(nèi)容包裹在一個(gè)對(duì)象中,在模塊內(nèi)部可以很容易找到導(dǎo)出的內(nèi)容。
只使用 export default 具有一致性,不會(huì)因?yàn)檫^(guò)多導(dǎo)出方式造成混淆,在使用的時(shí)候也更加方便。
我們已經(jīng)熟悉了 export 的 API 和注意事項(xiàng),下面來(lái)看 import 語(yǔ)句。
import作為與 export 相對(duì)的語(yǔ)句,import 可以讓我們導(dǎo)入另一個(gè)模塊中的內(nèi)容。模塊的加載方式,在瀏覽器端主要依靠 Babel 實(shí)現(xiàn)。而在內(nèi)部 import 語(yǔ)句的實(shí)現(xiàn)也幾乎是和 CommonJS 的 require 語(yǔ)句一樣。
讓我們用 lodash 來(lái)說(shuō)明。下面的語(yǔ)句簡(jiǎn)單地加載了 Lodash 模塊到我們自己的模塊,它沒有創(chuàng)建任何變量,但它將會(huì)執(zhí)行 lodash 模塊頂層代碼的內(nèi)容。
import "lodash"
在講導(dǎo)入綁定之前,我們需要先明確的是,跟 export 語(yǔ)句類似,import 語(yǔ)句也只能在模塊的頂層代碼使用。這能讓編譯器更好地處理解析工作,也能幫助其他靜態(tài)分析工具解析我們的代碼。
Importing Default Exports在 CommonJS 中,我們使用 require 導(dǎo)入內(nèi)容:
var _ = require("lodash")
在 ES6 模塊中,我們只需要為導(dǎo)入的綁定起一個(gè)名字:
import _ from "lodash"
我們也可以導(dǎo)入具名導(dǎo)出的內(nèi)容。
Importing Named Exports這個(gè)語(yǔ)法跟 ES6 的解構(gòu)賦值很相似,但是也不太一樣:
import { map, reduce } from "lodash"
跟解構(gòu)賦值不同的其中一點(diǎn)是,你可以為導(dǎo)入的綁定創(chuàng)建別名,可以同時(shí)使用有別名和沒有別名的導(dǎo)入。
import { cloneDeep as clone, map } from "lodash"
也可以同時(shí)使用具名和默認(rèn)的導(dǎo)入,如果要在花括號(hào)內(nèi)使用默認(rèn)導(dǎo)入,需要使用 default 關(guān)鍵字,當(dāng)然也可以給它起個(gè)別名,或者像第三行那樣:
import { default, map } from "lodash" import { default as _, map } from "lodash" import _, { map } from "lodash"import All The Things
我們也可以導(dǎo)入一個(gè)模塊中的整個(gè)命名空間。import * 這個(gè)語(yǔ)法后面必須跟一個(gè)別名,這個(gè)別名中就存放了導(dǎo)入模塊的所有綁定。如果里面包含一個(gè)默認(rèn)導(dǎo)出,那么它放被放在了 alias.default 中
import * as _ from "lodash"Conclusions
我們今天可以直接使用 ES6 模塊,得益于 Babel 編譯器借助了 CommonJS 模塊的實(shí)現(xiàn)。這其中的一個(gè)好處就是 CommonJS 和 ES6 模塊之間是兼容的,即我們可以在 ES6 模塊中直接寫 CommonJS 的語(yǔ)法。
ES6 模塊系統(tǒng)看起來(lái)很棒,而它也是 JavaScript 中的一個(gè)最重要的功能。希望在不久的將來(lái),模塊加載 API 可以最終敲定并直接在瀏覽器端實(shí)現(xiàn)。
原文鏈接
歡迎關(guān)注我的公眾號(hào):碼力全開(codingonfire)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/105660.html
摘要:哈哈,我理解,架構(gòu)就是骨架,如下圖所示譯年月個(gè)有趣的和庫(kù)前端掘金我們創(chuàng)辦的使命是讓你及時(shí)的了解開發(fā)中最新最酷的趨勢(shì)。 翻譯 | 上手 Webpack ? 這篇就夠了! - 掘金譯者:小 boy (滬江前端開發(fā)工程師) 本文原創(chuàng),轉(zhuǎn)載請(qǐng)注明作者及出處。 原文地址:https://www.smashingmagazine.... JavaSrip... 讀 Zepto 源碼之代碼結(jié)構(gòu) - ...
摘要:即將立秋的課多周刊第期我們的微信公眾號(hào),更多精彩內(nèi)容皆在微信公眾號(hào),歡迎關(guān)注。若有幫助,請(qǐng)把課多周刊推薦給你的朋友,你的支持是我們最大的動(dòng)力。課多周刊機(jī)器人運(yùn)營(yíng)中心是如何玩轉(zhuǎn)起來(lái)的分享課多周刊是如何運(yùn)營(yíng)并堅(jiān)持下來(lái)的。 即將立秋的《課多周刊》(第2期) 我們的微信公眾號(hào):fed-talk,更多精彩內(nèi)容皆在微信公眾號(hào),歡迎關(guān)注。 若有幫助,請(qǐng)把 課多周刊 推薦給你的朋友,你的支持是我們最大...
摘要:即將立秋的課多周刊第期我們的微信公眾號(hào),更多精彩內(nèi)容皆在微信公眾號(hào),歡迎關(guān)注。若有幫助,請(qǐng)把課多周刊推薦給你的朋友,你的支持是我們最大的動(dòng)力。課多周刊機(jī)器人運(yùn)營(yíng)中心是如何玩轉(zhuǎn)起來(lái)的分享課多周刊是如何運(yùn)營(yíng)并堅(jiān)持下來(lái)的。 即將立秋的《課多周刊》(第2期) 我們的微信公眾號(hào):fed-talk,更多精彩內(nèi)容皆在微信公眾號(hào),歡迎關(guān)注。 若有幫助,請(qǐng)把 課多周刊 推薦給你的朋友,你的支持是我們最大...
2017-10-01 前端日?qǐng)?bào) 精選 網(wǎng)頁(yè)保存為圖片及高清截圖的優(yōu)化方法前端最佳實(shí)踐(一)——DOM操作Vue 2.0學(xué)習(xí)筆記:v-bindReact Router v4 之代碼分割:從放棄到入門js實(shí)用的十個(gè)小技巧Netflix/falcor: A JavaScript library for efficient data fetchinglllyasviel/style2paints: ske...
閱讀 4604·2021-09-22 14:57
閱讀 565·2019-08-30 15:56
閱讀 2672·2019-08-30 15:53
閱讀 2245·2019-08-29 14:15
閱讀 1692·2019-08-28 17:54
閱讀 564·2019-08-26 13:37
閱讀 3484·2019-08-26 10:57
閱讀 1049·2019-08-26 10:32