您好,登錄后才能下訂單哦!
這篇文章主要講解了“Module模塊化編程的優點有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Module模塊化編程的優點有哪些”吧!
隨著前端功能越來越復雜,前端代碼日益膨脹,為了減少維護成本,提高代碼的可復用性,前端模塊化勢在必行。
所有js文件都在一個html中引入,造成以下不良影響:
請求過多。首先我們要依賴多個模塊,那樣就會發送多個請求,導致請求過多
依賴模糊。我們不知道他們的具體依賴關系是什么,也就是說很容易因為不了解他們之間的依賴關系導致加載先后順序出錯。
難以維護。以上兩種原因就導致了很難維護,很可能出現牽一發而動全身的情況導致項目出現嚴重的問題。
webpack中是這樣定義的:
在模塊化編程中,開發者將程序分解成離散功能塊(discrete chunks of functionality),并稱之為模塊。 每個模塊具有比完整程序更小的接觸面,使得校驗、調試、測試輕而易舉。 精心編寫的模塊提供了可靠的抽象和封裝界限,使得應用程序中每個模塊都具有條理清楚的設計和明確的目的。
模塊應該是職責單一、相互獨立、低耦合的、高度內聚且可替換的離散功能塊。
模塊化的概念
模塊化是一種處理復雜系統分解成為更好的可管理模塊的方式,它可以把系統代碼劃分為一系列職責單一,高度解耦且可替換的模塊,系統中某一部分的變化將如何影響其它部分就會變得顯而易見,系統的可維護性更加簡單易得。
模塊化是一種分治的思想,通過分解復雜系統為獨立的模塊實現細粒度的精細控制,對于復雜系統的維護和管理十分有益。模塊化也是組件化的基石,是構成現在色彩斑斕的前端世界的前提條件。
為什么需要模塊化
前端開發和其他開發工作的主要區別,首先是前端是基于多語言、多層次的編碼和組織工作,其次前端產品的交付是基于瀏覽器,這些資源是通過增量加載的方式運行到瀏覽器端,如何在開發環境組織好這些碎片化的代碼和資源,并且保證他們在瀏覽器端快速、優雅的加載和更新,就需要一個模塊化系統。
可維護性。 因為模塊是獨立的,一個設計良好的模塊會讓外面的代碼對自己的依賴越少越好,這樣自己就可以獨立去更新和改進。
命名空間。 在 JavaScript 里面,如果一個變量在最頂級的函數之外聲明,它就直接變成全局可用。因此,常常不小心出現命名沖突的情況。使用模塊化開發來封裝變量,可以避免污染全局環境。
重用代碼。 我們有時候會喜歡從之前寫過的項目中拷貝代碼到新的項目,這沒有問題,但是更好的方法是,通過模塊引用的方式,來避免重復的代碼庫。我們可以在更新了模塊之后,讓引用了該模塊的所有項目都同步更新,還能指定版本號,避免 API 變更帶來的麻煩。
1. 最簡單粗暴的方式
function fn1(){ // ... } function fn2(){ // ... }
通過 script 標簽引入文件,調用相關的函數。這樣需要手動去管理依賴順序,容易造成命名沖突,污染全局,隨著項目的復雜度增加維護成本也越來越高。
2. 用對象來模擬命名空間
var output = { _count: 0, fn1: function(){ // ... } }
這樣可以解決上面的全局污染的問題,有那么點命名空間的意思,但是隨著項目復雜度增加需要越來越多的這樣的對象需要維護,不說別的,取名字都是個問題。最關鍵的還是內部的屬性還是可以被直接訪問和修改。
3. 閉包
var module = (function(){ var _count = 0; var fn1 = function (){ // ... } var fn2 = function fn2(){ // ... } return { fn1: fn1, fn2: fn2 } })() module.fn1(); module._count; // undefined
這樣就擁有獨立的詞法作用域,內存中只會存在一份 copy。這不僅避免了外界訪問此 IIFE 中的變量,而且又不會污染全局作用域,通過 return 暴露出公共接口供外界調用。這其實就是現代模塊化實現的基礎。
4. 更多
還有基于閉包實現的松耦合拓展、緊耦合拓展、繼承、子模塊、跨文件共享私有對象、基于 new 構造的各種方式,這種方式在現在看來都不再優雅。
// 松耦合拓展 // 這種方式使得可以在不同的文件中以相同結構共同實現一個功能塊,且不用考慮在引入這些文件時候的順序問題。 // 缺點是沒辦法重寫你的一些屬性或者函數,也不能在初始化的時候就是用module的屬性。 var module = (function(my){ // ... return my })(module || {}) // 緊耦合拓展(沒有傳默認參數) // 加載順序不再自由,但是可以重載 var module = (function(my){ var old = my.someOldFunc my.someOldFunc = function(){ // 重載方法,依然可通過old調用舊的方法... } return my })(module)
歷史上,JavaScript 一直沒有模塊(module)體系,無法將一個大程序拆分成互相依賴的小文件,再用簡單的方法拼裝起來。其他語言都有這項功能,比如 Ruby 的require、Python 的import,甚至就連 CSS 都有@import,但是 JavaScript 任何這方面的支持都沒有,這對開發大型的、復雜的項目形成了巨大障礙。
在 ES6 之前,社區制定了一些模塊加載方案,最主要的有 CommonJS 和 AMD 兩種。前者用于服務器,后者用于瀏覽器。ES6 在語言標準的層面上,實現了模塊功能,而且實現得相當簡單,完全可以取代 CommonJS 和 AMD 規范,成為瀏覽器和服務器通用的模塊解決方案。
ES6 模塊的設計思想是盡量的靜態化,使得編譯時就能確定模塊的依賴關系,以及輸入和輸出的變量。CommonJS 和 AMD 模塊,都只能在運行時確定這些東西。比如,CommonJS 模塊就是對象,輸入時必須查找對象屬性。
目前實現模塊化的規范主要有:
CommonJS
CommonJS 是以在瀏覽器環境之外構建 JavaScript 生態系統為目標而產生的項目,比如在服務器和桌面環境中。
采用同步加載模塊的方式,也就是說只有加載完成,才能執行后面的操作。CommonJS 代表:Node 應用中的模塊,通俗的說就是你用 npm 安裝的模塊。
它使用 require 引用和加載模塊,exports 定義和導出模塊,module 標識模塊。使用 require 時需要去讀取并執行該文件,然后返回 exports 導出的內容。
CMD
CMD(Common Module Definition)
CMD是SeaJS在推廣過程中生產的對模塊定義的規范,在Web瀏覽器端的模塊加載器中,SeaJS與RequireJS并稱,SeaJS作者為阿里的玉伯。
CMD規范專門用于瀏覽器端,模塊的加載是異步的,模塊使用時才會加載執行。CMD規范整合了CommonJS和AMD規范的特點。在 Sea.js 中,所有 JavaScript 模塊都遵循 CMD模塊定義規范。
AMD
AMD(Asynchronous Module Definition)
異步模塊定義,所謂異步是指模塊和模塊的依賴可以被異步加載,他們的加載不會影響它后面語句的運行。有效避免了采用同步加載方式中導致的頁面假死現象。AMD代表:RequireJS。
AMD一開始是CommonJS規范中的一個草案,全稱是Asynchronous Module Definition,即異步模塊加載機制。后來由該草案的作者以RequireJS實現了AMD規范,所以一般說AMD也是指RequireJS。
RequireJS是一個工具庫,主要用于客戶端的模塊管理。它的模塊管理遵守AMD規范,RequireJS的基本思想是,通過define方法,將代碼定義為模塊;通過require方法,實現代碼的模塊加載。
ES6模塊
ES6模塊的設計思想,是盡量的靜態化,使得編譯時就能確定模塊的依賴關系,以及輸入和輸出的變量。所以說ES6是編譯時加載,不同于CommonJS的運行時加載(實際加載的是一整個對象),ES6模塊不是對象,而是通過export命令顯式指定輸出的代碼,輸入時也采用靜態命令的形式。
ES6 的模塊自動采用嚴格模式,不管你有沒有在模塊頭部加上”use strict”;。
嚴格模式主要有以下限制。
變量必須聲明后再使用
函數的參數不能有同名屬性,否則報錯
不能使用with語句
不能對只讀屬性賦值,否則報錯
不能使用前綴 0 表示八進制數,否則報錯
不能刪除不可刪除的屬性,否則報錯
不能刪除變量delete prop,會報錯,只能刪除屬性delete global[prop]
eval不會在它的外層作用域引入變量
eval和arguments不能被重新賦值
arguments不會自動反映函數參數的變化
不能使用arguments.callee
不能使用arguments.caller
禁止this指向全局對象
不能使用fn.caller和fn.arguments獲取函數調用的堆棧
增加了保留字(比如protected、static和interface)
上面這些限制,模塊都必須遵守。
感謝各位的閱讀,以上就是“Module模塊化編程的優點有哪些”的內容了,經過本文的學習后,相信大家對Module模塊化編程的優點有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。