爲何想起來作這樣一個專題呢,答案應該是爲了勉勵面試筆試秋招中的本身吧!
並且也是爲了和我同樣的你。javascript
我叫王彬,如今是百度首頁業務部(原網頁搜團隊索部FE前端)的實習FE,
兩天前我得知我所在的部門只有兩個hc,並且要分給策略rd,
這就意味着我要面臨千軍萬馬過獨木橋的「秋招」。
可能個人描述有點誇張,可是此時此刻的真的是這麼感受的。
我以爲以我如今的水平,可能不會有一家大公司要我,因此我發自心裏的厭惡秋招!
可是必須面對!
一塊兒努力吧,但願本身能夠一直寫下去。
所寫的文章確定有不完善的地方,但願看的朋友能夠指正,我會虛心接受一切聲音。
好,言歸正傳!
我今天要寫的是關於Amd和Cmdhtml
首先來看這個http://www.zhihu.com/question...
玉伯知乎上的回答前端
說到Amd和Cmd,你可能和我同樣,最早想到的就是require.js以及sea.js
由於二者分別的是Amd和Cmd的表明
在開始深刻了解Amd以及Cmd以前,我和你們同樣,只是知道這都是js模塊化加載的工具
至於模塊化加載的好處天然沒必要多說,用過的應該都懂
那麼咱們就從require.js和sea.js蔓延開來說講Amd和Cmdjava
Amd是指Asynchronous Module Definition,異步的模塊加載機制。是在推廣require.js時對模塊規範化產出。
node
如下的內容引自阮一峯老師的博客http://www.ruanyifeng.com/blo...程序員
要說Amd就要先從Common.js提及。面試
2009年,美國程序員Ryan Dahl創造了node.js項目,將javascript語言用於服務器端編程。
node.js的模塊系統,就是參照CommonJS規範實現的。在CommonJS中,有一個全局性方法require(),用於加載模塊。假定有一個數學模塊math.js,就能夠像下面這樣加載。算法
var math = require('math'); math.add(2,3); // 5
有了服務器端模塊之後,很天然地,你們就想要客戶端模塊。並且最好二者可以兼容,一個模塊不用修改,在服務器和瀏覽器均可以運行。
可是,因爲一個重大的侷限,使得CommonJS規範不適用於瀏覽器環境。仍是上一節的代碼,若是在瀏覽器中運行,會有一個很大的問題,你能看出來嗎?編程
第二行math.add(2,3),在第一行require('math')以後運行,所以必須等math.js加載完成。也就是說,若是加載時間很長,整個應用就會停在那裏等。數組
這對服務器端不是一個問題,由於全部的模塊都存放在本地硬盤,能夠同步加載完成,等待時間就是硬盤的讀取時間。
可是,對於瀏覽器,這倒是一個大問題,由於模塊都放在服務器端,等待時間取決於網速的快慢,可能要等很長時間,瀏覽器處於"假死"狀態。
所以,瀏覽器端的模塊,不能採用"同步加載"(synchronous),只能採用"異步加載"(asynchronous)。這就是AMD規範誕生的背景。
下面具體的用法,看一下下面的舉例(具體詳細配置以及使用方法請你們查看require.js官方文檔):
//經過數組引入依賴 ,回調函數經過形參傳入依賴 define(['someModule1', ‘someModule2’], function (someModule1, someModule2) { function foo () { // something someModule1.test(); } return {foo: foo} });
AMD規範容許輸出模塊兼容CommonJS規範,這時define方法以下:
define(function (require, exports, module) { var reqModule = require("./someModule"); requModule.test(); exports.asplode = function () { //something } });
可是值得注意的是:
仍然按照這種寫法,加載的模塊仍會被提早讀取且加載(記住是讀取且加載,後面有用),
與下面的這種寫法效果同樣!
define(['./someModule'], function (require, exports, module, reqModule) { requModule.test(); exports.asplode = function () { // something } });
所以咱們能夠得出結論:
1.Amd推崇的是依賴前置。
2.Amd對加載的模塊是提早讀取並加載。
Cmd是指Common Module Definition,異步的模塊加載機制。是在推廣sea.js時對模塊規範化產出。
說到Cmd,你們千萬不要望文生義,認爲這和Common.js在服務器端的加載方式相同,其實並不同。
其實Cmd更像是Amd和Common.js的升級版,結合了二者的優勢。
Common.js能夠作到當須要這個模塊時,再讀取並加載。
Amd能夠作到避免Common.js的 「臨時讀取並加載文件」,它是提早讀取並加載。
而Cmd能夠作到的是,「提早讀取文件,但在須要再加載」,這樣能夠避免瀏覽器臨時加載文件的假死,也能夠避免提早加載引發的邏輯問題。
具體的邏輯問題指什麼呢?咱們來看這篇圖文並茂的講解:
請戳:https://www.douban.com/note/2...
請仔細看,若是有點懵的話,像我同樣,再看兩遍。
因此你們叫sea.js懶加載,也就是 「as lazy as possible」,若是你面試的時候說出這句話,面試官必定對你另眼相看。這也是Cmd的標誌!
懶加載能夠很好的做爲判別Amd和Cmd的方法哈!
所以咱們能夠總結出:
1.Cmd推崇的是就近依賴。
2.Cmd對加載的模塊是提早讀取並不加載,而是在須要時加載。
我在百度實習時接觸到過一個框架,用於百度PC首頁和PAD首頁的模塊化開發。
這個框架是F框架(移動端因爲性能優化的要求使用的是B框架,esl.js),感興趣的朋友能夠深刻了解一下。
F框架有一個特色,
F.module('hello', function () { // require('world'); // do something... })
若是代碼這麼寫,雖然require('world')被註釋掉了
可是world這個模塊依然會被加載,你們知道爲何嗎?
答案是:由於F框架遵循的是Amd規範,會正則匹配factory也就是模塊的主體函數中的require字段,一但匹配到就會進行前置讀取並加載。
因此會出現這種現象。
這個例子但願能夠幫助你們理解。
最後再看遍文章開頭提到的玉伯大神的問答 http://www.zhihu.com/question... 加深理解
文章的內容並非所有原創,
我在網上借鑑了許多老師的經驗
http://www.zhihu.com/question...
https://www.douban.com/note/2...
http://zccst.iteye.com/blog/2...
http://www.ruanyifeng.com/blo...
感謝以上全部老師的智慧結晶!
下一次想和你們聊聊js原型那些事,爭取立刻更新!對啦,你們有沒有什麼複習數據結構與算法的好辦法,但願數據結構與算法大神指點明津!