2018-9-14 seo達(dá)人
如果您想訂閱本博客內(nèi)容,每天自動(dòng)發(fā)到您的郵箱中, 請(qǐng)點(diǎn)這里
了解一個(gè)技術(shù),首先要了解這個(gè)技術(shù)產(chǎn)生的背景及解決的問(wèn)題,而不應(yīng)該只是單純的知道該怎么用。之前的狀態(tài)可能就是只是為了了解而了解,并不知道實(shí)際產(chǎn)生的原因及帶來(lái)的好處,所以今天就來(lái)總結(jié)一下。
來(lái)看百度百科的定義
模塊化程序設(shè)計(jì)是指在進(jìn)行程序設(shè)計(jì)時(shí)將一個(gè)大程序按照功能劃分為若干小程序模塊,每個(gè)小程序模塊完成一個(gè)確定的功能,并在這些模塊之間建立必要的聯(lián)系,通過(guò)模塊的互相協(xié)作完成整個(gè)功能的程序設(shè)計(jì)方法。
比如 java 的 import,C# 的 using。我的理解是通過(guò)模塊化編程,可以將不同的功能獨(dú)立出來(lái),修改某個(gè)功能時(shí)不會(huì)對(duì)其他功能產(chǎn)生影響。
來(lái)看下面一個(gè)例子
假設(shè)上面三個(gè)文件,B.js 引用了 A.js 里面的內(nèi)容,C.js 又引用了 B.js 里面的內(nèi)容,如果編寫(xiě) C.js 的人只知道引用了 B.js,那他就不會(huì)引用 A.js 就會(huì)導(dǎo)致程序出錯(cuò),而且文件的引用順序也不能出錯(cuò)。給整體代碼的調(diào)試修改帶來(lái)不便。
還有個(gè)問(wèn)題,上述代碼暴露了兩個(gè)全局變量,容易造成全局變量的污染
AMD 即 Asynchronous Module Definition(異步模塊定義)。采取異步加載的方式加載模塊,模塊的加載不會(huì)影響它后面的語(yǔ)句執(zhí)行。而且只有用到的時(shí)候才會(huì)去加載相關(guān)文件,屬于瀏覽器端的標(biāo)準(zhǔn)
假設(shè)下面這種情況
頁(yè)面上先打印 1
,然后才會(huì)打印 2018 年 8 月 9 日
。因此 AMD 的加載并不會(huì)影響后續(xù)的語(yǔ)句執(zhí)行。
如果不是異步加載會(huì)出現(xiàn)什么情況呢
后面的語(yǔ)句需要等待 a 加載完成才能執(zhí)行,如果加載時(shí)間過(guò)長(zhǎng),整個(gè)程序都會(huì)卡在這。因此,瀏覽器不能同步加載資源,這也是 AMD 的產(chǎn)生背景。
AMD 是在瀏覽器端實(shí)現(xiàn)模塊化開(kāi)發(fā)的規(guī)范。由于該規(guī)范不是 JavaScript 原始支持的,使用 AMD 規(guī)范進(jìn)行開(kāi)發(fā)的時(shí)候需要引入第三方的庫(kù)函數(shù),也就是 RequireJS。
RequireJS 主要解決的問(wèn)題
下面來(lái)看看如何使用 require.js
要想使用 require.js,首先要 define
factory:為模塊初始化要執(zhí)行的函數(shù)或?qū)ο?。如果為函?shù),它應(yīng)該只被執(zhí)行一次。如果是對(duì)象,此對(duì)象應(yīng)該為模塊的輸出值。
具體的規(guī)范說(shuō)明可以參考 AMD (中文版)
舉個(gè)例子,創(chuàng)建一個(gè)名為 “alpha” 的模塊,使用了 require,exports,和名為 “beta” 的模塊:
一個(gè)返回對(duì)象的匿名模塊:
一個(gè)沒(méi)有依賴(lài)性的模塊可以直接定義對(duì)象:
如何使用
AMD 采用 require 語(yǔ)句加載模塊
例如
具體的使用方法如下
假設(shè)這里有 4 個(gè)文件,util.js,a-util.js 引用了 util.js,a.js 引用了 a-util.js,main.js 引用了 a.js。
其中,data-main 屬性的作用是加載網(wǎng)頁(yè)程序的主模塊。
上例演示了一個(gè)主模塊最簡(jiǎn)單的寫(xiě)法,默認(rèn)情況下,require.js 假設(shè)依賴(lài)和主模塊在同一個(gè)目錄。
使用 require.config()
方法可以對(duì)模塊的加載行為進(jìn)行自定義。require.config()
就寫(xiě)在主模塊(main.js)的頭部,參數(shù)是一個(gè)對(duì)象,這個(gè)對(duì)象的 paths 屬性指定各個(gè)模塊的加載路徑
還有一種方法是改變基礎(chǔ)目錄(baseUrl)
commonJS 是 nodejs 的模塊化規(guī)范,現(xiàn)在被大量用在前端,由于構(gòu)建工具的高度自動(dòng)化,使得使用 npm 的成本非常低。commonJS 不會(huì)異步加載 JS,而是同步一次性加載出來(lái)
在 commonJS 中,有一個(gè)全局性的方法 require(),用于加載模塊,例如
然后,就可以調(diào)用 util 提供的方法了
commonJS 對(duì)于模塊的定義分三種,模塊定義(exports),模塊引用(require)和模塊標(biāo)示(module)
exports() 對(duì)象用于導(dǎo)出當(dāng)前模塊的變量或方法,唯一的導(dǎo)出口。require() 用來(lái)引入外部模塊。module 對(duì)象代表模塊本身。
舉個(gè)栗子
或者下面這種方式
ES6 模塊的設(shè)計(jì)思想是盡量靜態(tài)化,使得編譯時(shí)就能確定模塊的依賴(lài)關(guān)系,以及輸入和輸出的變量,而 CommonJS 和 AMD 模塊都只能在運(yùn)行時(shí)確定這些關(guān)系。如 CommonJS 加載方式為 “運(yùn)行時(shí)加載”,ES6 的加載方式為 “編譯時(shí)加載” 或者靜態(tài)加載,即 ES6 可以在編譯時(shí)就完成模塊加載,效率比 CommonJS 模塊的加載方式高。
ES6 模塊自動(dòng)采用嚴(yán)格模式,不管有沒(méi)有在模塊頭部加上 “use strict”。
ES6 export 語(yǔ)句輸出的接口與其對(duì)應(yīng)的值是動(dòng)態(tài)綁定關(guān)系,即通過(guò)該接口可以取到模塊內(nèi)部實(shí)時(shí)的值。而 CommonJS 模塊輸出的是值的緩存,不存在動(dòng)態(tài)更新。
ES6 與 CommonJS 模塊的差異
第二個(gè)差異是因?yàn)?CommonJS 加載的是一個(gè)對(duì)象(即 Module.exports 屬性),該對(duì)象只有在腳本運(yùn)行結(jié)束時(shí)才會(huì)生成,而 ES6 模塊不是對(duì)象,它的對(duì)外接口只是一種靜態(tài)定義,在代碼靜態(tài)解析階段就會(huì)生成。
CommonJS 采用了服務(wù)器優(yōu)先的策略,使用同步方式加載模塊,而 AMD 采用異步加載的方式。所以如果需要使用異步加載 js 的話(huà)建議使用 AMD,而當(dāng)項(xiàng)目使用了 npm 的情況下建議使用 CommonJS。
藍(lán)藍(lán)設(shè)計(jì)( sillybuy.com )是一家專(zhuān)注而深入的界面設(shè)計(jì)公司,為期望卓越的國(guó)內(nèi)外企業(yè)提供卓越的UI界面設(shè)計(jì)、BS界面設(shè)計(jì) 、 cs界面設(shè)計(jì) 、 ipad界面設(shè)計(jì) 、 包裝設(shè)計(jì) 、 圖標(biāo)定制 、 用戶(hù)體驗(yàn) 、交互設(shè)計(jì)、 網(wǎng)站建設(shè) 、平面設(shè)計(jì)服務(wù)。
藍(lán)藍(lán)設(shè)計(jì)的小編 http://sillybuy.com