摘要:前兩天有朋友拿了這樣一段代碼來問我,我想把一段代碼寫成模塊化的樣子,你幫我看看是不是這樣的。的一個(gè)好處在與依賴前置,所有被使用到的模塊都會(huì)被提前加載好,從而加快運(yùn)行速度。
前兩天有朋友拿了這樣一段代碼來問我,“我想把一段代碼寫成模塊化的樣子,你幫我看看是不是這樣的?!?,代碼大概是這樣的:
(function(global) { var myModules = { name: "xxx", location: "chengdu", intro: function() { return `his name is ${myModules.name} and come from ${myModules.location}` }, } // some other code... if(typeof module === "undefined") global.myModules = myModules else module.exports = myModules })(this)
“可是我這段代碼在全局還是能myModules這個(gè)屬性?。俊?br>我一臉懵,還有這種操作,為什么你的立即執(zhí)行函數(shù)要把this傳進(jìn)去呢,這樣不久將里面的內(nèi)容掛在到了window上了嗎,他似懂非懂,我只好說,你可能需要回頭去看看AMD和CMD規(guī)范了,我大概能夠理解這其中的緣由,畢竟這段時(shí)間前端發(fā)展的速度飛快,加上webpack也不需要自己配,包括vue,react,angular在內(nèi)的框架類庫(kù)都有一鍵生成項(xiàng)目的工具,從而只需要使用下import * from "*"和export default {},而這種便利會(huì)讓新人不再需要去學(xué)習(xí)基本原理就能快速上手,畢竟現(xiàn)在都ES2018了呀。
對(duì)象形式
最開始的時(shí)候,為了減少全局變量,一般會(huì)使用一個(gè)對(duì)象的方式來對(duì)所有的變量方法進(jìn)行一個(gè)包裝:
var obj = { a: 1, b: 2, sum: function(val) { return obj.a + obj.b + val }, rest: function(val) { return val - obj.a - obj.b } }
以上代碼似乎解決了全局變量的問題,但是其中的a和b兩個(gè)變量還是可能被修改,其中包含的進(jìn)化有限。
立即執(zhí)行函數(shù)
回過頭來看文章開頭的代碼,姑且不論以上代碼的錯(cuò)誤之處,稍作修改,這算是最初的一種關(guān)于JavaScript模塊化的開端,立即執(zhí)行函數(shù):
var add = (function(){ var a = 1 var b = 2 function sum(count){ return a + b + count } function rest(count){ return count - a - b } return { rest: rest, sum: sum } })()
這就是一種最簡(jiǎn)單的模塊化的方式,利用閉包的特性,設(shè)置了兩個(gè)只有在被暴露出來的add和reduce方法內(nèi)部才能訪問到的兩個(gè)變量,從而保證了函數(shù)的局部變量不可被修改的特性,這次的進(jìn)化用到了閉包,從而實(shí)現(xiàn)了部分有效的目的。
放大模式
其實(shí)開頭的代碼更符合另外一種叫做放大模式的方法,不過一般來說不會(huì)講window作為放大模式中被傳入的對(duì)象
var globalObject = { fn1: function() { // todo... }, // ... } globalObject = (function(obj) { var name = "xxx" var location = "xxx" function sum(val) { /* todo... */ } function rest(val) { /* todo... */ } obj.sum = sum obj.rest = rest return obj })(globalObject)
以這種形式來寫,可以讓全局變量盡量的減少,同時(shí)讓一個(gè)立即執(zhí)行函數(shù)中的代碼盡量做到精簡(jiǎn)。
但是這種放大模式也存在著問題,比如當(dāng)globalObject內(nèi)容足夠多的時(shí)候,很可能會(huì)造成命名重復(fù)的情況,并且以上所有的方式都不可以減少script標(biāo)簽的數(shù)量,所以,我們還是會(huì)被模塊的加載順序,命名空間沖突等問題所困擾,這時(shí)候,我們應(yīng)該跨入新時(shí)代了。
CMD規(guī)范
CMD規(guī)范來自阿里的框架seajs,當(dāng)初確實(shí)有挺多人使用,不過現(xiàn)階段已經(jīng)不再維護(hù)了,我也不會(huì),就暫時(shí)不說了,只列出來。
commonjs
同時(shí),從2009年開始,JavaScript就不再只是一種瀏覽器端的腳本語(yǔ)言了,nodejs的出現(xiàn)讓使用js開發(fā)服務(wù)端變成了可能,隨著node出現(xiàn)的東西還有一個(gè)叫做commonjs的規(guī)范,在這個(gè)規(guī)范中,每個(gè)文件都是一個(gè)模塊,有著自己的作用域。
譬如,如下代碼
// 文件a.js var a = 1 // 文件b.js console.log(a) // a is not defined.
在這樣的特性下,a.js和b.js都有著自己獨(dú)有的作用域,要在b中對(duì)a進(jìn)行訪問,就需要一種加載機(jī)制,一般來說,有兩種方法能夠做到:
方法1
// 文件a.js global.a = 1 // 文件b.js console.log(a) // 1
這種方法掛載在global上,當(dāng)然是不可取的。
方法2
// 文件a.js exports.a = 1 // 文件b.js var moduleA = require("./a") console.log(moduleA.a)
AMD規(guī)范
requirejs的出現(xiàn)讓script標(biāo)簽的減少變成了可能,在requirejs的時(shí)代,我們一般會(huì)使用jQuery,underscore這類的類庫(kù),如果按照往常的樣子我們會(huì)將代碼寫成下面這副模樣:
這樣的代碼乍一看似乎沒什么問題,但是當(dāng)一個(gè)項(xiàng)目的代碼量上了一個(gè)量級(jí),一切就變得不是這么回事兒了,你會(huì)被困在加載順序,加載時(shí)間的問題上,這也就是requirejs能夠出現(xiàn)的原因了。
在requirejs中,你可以如此改寫以上代碼:
// `index.js` require(["js/lib/jquery.min", "js/lib/underscore.min", "js/app/app"], function($, _, app) { /* todo... */ }) // `app.js` define(["js/lib/jquery.min", "js/lib/underscore.min"], function($, _) { /* todo... */ })
這里當(dāng)然顯得更加優(yōu)雅了,在requirejs的推廣過程中,AMD規(guī)范也就應(yīng)運(yùn)而生了,那么,requirejs或者說AMD規(guī)范到底解決了什么樣的問題呢,主要有幾點(diǎn):
AMD是“異步模塊定義”的縮寫,也就是說,其中內(nèi)容是異步加載的,從而讓頁(yè)面不被js的加載阻塞,最大程度上的避免了頁(yè)面假死等情況的產(chǎn)生。
AMD的一個(gè)好處在與依賴前置,所有被使用到的模塊都會(huì)被提前加載好,從而加快運(yùn)行速度。
那么,commonjs規(guī)范和AMD規(guī)范有什么區(qū)別呢
運(yùn)行環(huán)境不同,commonjs規(guī)范只能運(yùn)行在node端,而AMD規(guī)范則被用到瀏覽器端
由于運(yùn)行環(huán)境的不同,二者的加載機(jī)制也不同,commonjs中的require是同步執(zhí)行的,而AMD中則是異步的。
ES2015模塊化
在ES2015中,可以使用export, export default, import import * as 等操作符來作模塊化的功能,但是這個(gè)規(guī)范現(xiàn)在尚未被任何瀏覽器加入規(guī)范中,我目前的Chrome版本為63.0.3239.132,也無法原生支持,不過現(xiàn)階段我們幾乎都用上了這個(gè)規(guī)范,這一切都只能歸功于babel,webpack和rollup等新工具的出現(xiàn),既然如此,那就擁抱未來吧,不過有一點(diǎn),需要在了解原理的前提下,不然,倘若有一天,真的需要我們來封裝一個(gè)小小的模塊的時(shí)候,沒有了那些工具,我們?cè)搹暮蜗率帜亍?/p>
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/92746.html
摘要:反正在阿里巴巴,很多的運(yùn)維人員都說了,我們每年的工作中有一項(xiàng)不用寫的工作就是搬遷。未來我們確實(shí)相信阿里巴巴,可能在未來搬遷會(huì)相對(duì)更少一點(diǎn),我們認(rèn)為不能讓搬遷成為阿里巴巴運(yùn)維團(tuán)隊(duì)的核心競(jìng)爭(zhēng)力。以上,正是阿里巴巴的運(yùn)維團(tuán)隊(duì)所覆蓋的五個(gè)領(lǐng)域。 隨著大數(shù)據(jù)、機(jī)器學(xué)習(xí)和 AI 技術(shù)的飛速發(fā)展,智能化運(yùn)維成為運(yùn)維的熱點(diǎn)領(lǐng)域。Gartner 的報(bào)告宣稱,到 2020 年,將近 50% 的企業(yè)將會(huì)在他們的業(yè)...
摘要:程序人生從黑客到創(chuàng)業(yè),他說技術(shù)創(chuàng)業(yè)該這么做知道創(chuàng)宇,安全焦點(diǎn)民間白帽黑客組織核心成員,分享他創(chuàng)業(yè)感悟和踩過的那些坑。技術(shù)周刊由小組出品,匯聚一周好文章,周刊原文。 業(yè)界動(dòng)態(tài) 他們寫的代碼能上天!NASA的10條安全編碼準(zhǔn)則大公開 NASA的10條代碼編寫規(guī)范準(zhǔn)則 本期推薦 Node.js 中遇到含空格 URL 的神奇Bug——小范圍深入 HTTP 協(xié)議 本文闡述了博主遇到含空格 URL...
摘要:前端每周清單第期與模式變遷與優(yōu)化界面生成作者王下邀月熊編輯徐川前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。 showImg(https://segmentfault.com/img/remote/1460000013279448); 前端每周清單第 51 期: React Context A...
摘要:精讀前端可以從多個(gè)角度理解,比如規(guī)范框架語(yǔ)言社區(qū)場(chǎng)景以及整條研發(fā)鏈路。同是前端未來展望,不同的文章側(cè)重的格局不同,兩個(gè)標(biāo)題相同的文章內(nèi)容可能大相徑庭。作為使用者,現(xiàn)在和未來的主流可能都是微軟系,畢竟微軟在操作系統(tǒng)方面人才儲(chǔ)備和經(jīng)驗(yàn)積累很多。 1. 引言 前端展望的文章越來越不好寫了,隨著前端發(fā)展的深入,需要擁有非常寬廣的視野與格局才能看清前端的未來。 筆者根據(jù)自身經(jīng)驗(yàn),結(jié)合下面幾篇文章...
閱讀 2580·2023-04-25 17:33
閱讀 659·2021-11-23 09:51
閱讀 2967·2021-07-30 15:32
閱讀 1413·2019-08-29 18:40
閱讀 1957·2019-08-28 18:19
閱讀 1476·2019-08-26 13:48
閱讀 2253·2019-08-23 16:48
閱讀 2285·2019-08-23 15:56