做者:佑界 連接:https://www.zhihu.com/question/21347409/answer/17959757
來源:知乎 著做權歸做者全部,轉載請聯繫做者得到受權。 有必要簡單提一下二者的主要區別,CMD推崇依賴就近,能夠把依賴寫進你的代碼中的任意一行,例: define(function(require, exports, module) { var a = require('./a') a.doSomething() var b = require('./b') b.doSomething() }) 代碼在運行時,首先是不知道依賴的,須要遍歷全部的require關鍵字,找出後面的依賴。具體作法是將function toString後,用正則匹配出require關鍵字後面的依賴。顯然,這是一種犧牲性能來換取更多開發便利的方法。 而AMD是依賴前置的,換句話說,在解析和執行當前模塊以前,模塊做者必須指明當前模塊所依賴的模塊,表如今require函數的調用結構上爲: define(['./a','./b'],function(a,b){ a.doSomething() b.doSomething() }) 代碼在一旦運行到此處,能當即知曉依賴。而無需遍歷整個函數體找到它的依賴,所以性能有所提高,缺點就是開發者必須顯式得指明依賴——這會使得開發工做量變大,好比:當你寫到函數體內部幾百上千行的時候,突然發現須要增長一個依賴,你不得不回到函數頂端來將這個依賴添加進數組。 細心的讀者可能發現,到目前位置我討論的AMD和CMD的思想的關於依賴的部分,都只討論的「硬依賴」,也就是執行前確定須要的依賴,可是這不是所有的狀況。有的時候狀況是這樣的: // 函數體內:
if(status){ a.doSomething() } 在這個函數體內,可能依賴a,也可能不依賴a,我把這種可能的依賴成爲「軟依賴」。對於軟依賴固然能夠直接當硬依賴處理,可是這樣不經濟,由於依賴是不必定的,有可能加載了此處的依賴而實際上沒有用上。 對於軟依賴的處理,我推薦依賴前置+回調函數的實現形式。上面的例子簡單表述以下: // 函數體內:
if(status){ async(['a'],function(a){ a.doSomething() }) } 至此能夠對由commonJS衍生出來的方案作出總結了。在瀏覽器端來設計模塊加載機制,須要考慮依賴的問題。 咱們先把依賴分爲兩種,「強依賴」 —— 確定須要 和「弱依賴」 —— 可能須要。 對於強依賴,若是要性能優先,則考慮參照依賴前置的思想設計你的模塊加載器,我我的也更推崇這個方案一些;若是考慮開發成本優先,則考慮按照依賴就近的思想設計你的模塊加載器。 對於弱依賴,只須要將弱依賴的部分改寫到回調函數內便可。 若是如今我要實現一個模塊加載器,我會將強依賴前置,弱依賴採用異步回調函數的形式,其它的方法我認爲都只是語法糖而已,僅此就夠了。