JS的模塊化編程

1、模塊系統概述

模塊化是將系統分離成獨立功能的方法,這樣咱們須要什麼功能,就加載什麼功能。編程

當一個項目開發得愈來愈複雜時,會遇到一些問題,例如:命名衝突、文件依賴等。數組

文件依賴就是,A負責a.js組件的開發,B負責b.js組件的開發,在a.js文件裏面可能引用了b.js裏面的某一個變量,而在項目運行時a.jsb.js以前加載,這個時候就會出現一些錯誤信息,可是a.jsb.js自己都沒有錯誤,這就形成了咱們排錯的一些困難,這種問題咱們稱之爲文件依賴的問題。瀏覽器

因此使用模塊化開發時,能夠避免以上問題,而且提高開發效率。緩存

怎麼理解呢?在模塊化開發裏面,會把一個文件當作一個單獨的做用域存在,它們定義的變量、函數都不會相互影響。那若是在a.js裏面依賴了b.js,咱們就會進行聲明,經過這種方式也能夠減小文件依賴帶來的BUG。服務器

而提高開發效率主要是從代碼可複用性和可維護性來提高的。異步

總結:在生產的角度,模塊化開發是一種生產方式,這種方式生產效率高,維護成本低。模塊化

2、模塊化開發演變

一、全局函數

在早期的開發過程當中,就是將重複的代碼封裝搭到函數中,再將一系列的函數放到一個文件中。這種方式存在一些問題:存在污染全局變量、看不出相互的直接關係。函數

這種方式並不能解決根本的問題:命名衝突和文件依賴,因而演變爲對象命名空間。ui

二、對象命名空間

經過對象命名空間的形式,從某種程度上解決了變量命名衝突的問題,可是並不能從根本上解決命名衝突。存在問題:內部狀態可被外部改寫、命名空間愈來愈長。spa

三、私有公有成員分離

利用此種方式將函數包裝成一個獨立的做用域,私有空間的變量和函數不會影響到全局做用域。這種方式至關於如今寫插件的形式,解決了變量命名衝突的問題,可是沒有解決下降開發複雜度的問題。

四、CommonJS

CommonJS規範加載模塊是同步的,也就是說,加載完成才執行後面的操做。Node.js主要用於服務器編程,模塊都是存在本地硬盤中,加載比較快,因此Node.js採用CommonJS規範。

CommonJS規範分爲三部分:module(模塊標識)、require(模塊引用)、exports(模塊定義)。 module變量在每一個模塊內部,就表明當前模塊; exports屬性是對外的接口,用於導出當前模塊的方法或變量;require()用來加載外部模塊,讀取並執行js文件,返回該模塊的exports對象。

五、AMD(reuire.js)

AMD也就是異步模塊定義,它採用異步方式加載模塊,主要針對的是瀏覽器端的模塊規範。它經過define方法去定義模塊,require方法去加載模塊。

AMD定義:若是這個模塊還須要依賴其餘模塊,那麼define函數的第一個參數,必須是一個數組,指明該模塊的依賴。

define([tools], function(){});
複製代碼

AMD模塊的加載:

require(['modules'], callback);
複製代碼

第一個參數['modules'],是一個數組,裏面的成員就是須要加載的模塊;第二個參數callback,則是加載成功以後的回調函數,例如加載math.js:

require(['math'], function(){});
複製代碼

require()異步加載math,瀏覽器不會失去響應;它指定的回調函數,只有前面的模塊加載完成後纔會運行,解決了依賴性的問題。

六、CMD(sea.js)

CMD即通用模塊定義,CMD規範是國內發展出來的;正如AMD有require.js,CMD有個瀏覽器的實現sea.jssea.js要解決的問題和require.js同樣,只不過在模塊定義方式和模塊加載方式上有所不一樣。

在CMD規範中,一個模塊就是一個文件。代碼的書寫格式以下:

define(function (require, exports, module) {
    // 模塊代碼
})
複製代碼

require是能夠把其餘模塊導入進來的一個參數;exports能夠把模塊內的一些屬性和方法導出;module是一個對象,上面存儲了與當前模塊相關聯的一些屬性和方法。CMD是按需加載,推崇依賴就近,延遲執行。文件是提早加載好的,只有在require的時候纔去執行文件;

define(function(require, exports, module){
    var math = require('./math');
    math.add();
})
複製代碼

七、ES6 Module

在ES6以前沒有模塊化,爲了解決問題,提出了CommonJS,AMD,CMD;ES6模塊化汲取CommonJS和AMD的優勢,語法簡潔,支持異步加載,將來能夠成爲瀏覽器和服務器通用的模塊化解決方案。

ES6中模塊的定義:ES6新增了兩個關鍵字:exportimportexport用於把模塊裏的內容暴露出來,import用於引入模塊提供的功能。

ES6中模塊的加載,import加載模塊:

import{bar,foo,test,obj} from './lib'
foo();
複製代碼

注意:可使用export default命令,爲模塊指定默認輸出,一個模塊只能有一個默認輸出,因此export default只能使用一次。

ES6模塊運行機制:ES6模塊是動態引用,若是使用import從一個模塊加載變量(即import foo from 'foo'),變量不會被緩存,而是成爲一個指向被加載模塊的引用。等腳本執行時,根據只讀引用,到被加載的那個模塊中去取值。

相關文章
相關標籤/搜索