AMD 簡介
前端開發在近一兩年發展的非常快,JavaScript 作爲主流的開發語言得到了前所未有的熱捧。大量的前端框架出現了,這些框架都在嘗試着解決一些前端開發中的共性問題,但是實現又不盡相同。在這個背景下,CommonJS 社區誕生了,爲了讓前端框架發展的更加成熟,CommonJS 鼓勵開發人員一起在社區裏爲一些完成特定功能的框架制定規範。AMD(Asynchronous Module Definition)就是其中的一個規範。
傳統 JavaScript 代碼的問題
讓我們來看看一般情況下 JavaScript 代碼是如何開發的:通過script標籤來載入 JavaScript 文件,用全局變量來區分不同的功能代碼,全局變量之間的依賴關係需要顯式的通過指定其加載順序來解決,發佈應用時要通過工具來壓縮所有的 JavaScript 代碼到一個文件。當 Web 項目變得非常龐大,前端模塊非常多的時候,手動管理這些全局變量間的依賴關係就變得很困難,這種做法顯得非常的低效。
AMD 的引入
AMD 提出了一種基於模塊的異步加載 JavaScript 代碼的機制,它推薦開發人員將 JavaScript 代碼封裝進一個個模塊,對全局對象的依賴變成了對其他模塊的依賴,無須再聲明一大堆的全局變量。通過延遲和按需加載來解決各個模塊的依賴關係。模塊化的 JavaScript 代碼好處很明顯,各個功能組件的鬆耦合性可以極大的提升代碼的複用性、可維護性。這種非阻塞式的併發式快速加載 JavaScript 代碼,使 Web 頁面上其他不依賴 JavaScript 代碼的 UI 元素,如圖片、CSS 以及其他 DOM 節點得以先加載完畢,Web 頁面加載速度更快,用戶也得到更好的體驗。
CommonJS 的 AMD 規範中只定義了一個全局的方法,如清單 1 所示。
清單 1. AMD 規範
define(id?, dependencies?, factory);
該方法用來定義一個 JavaScript 模塊,開發人員可以用這個方法來將部分功能模塊封裝在這個 define 方法體內。
id 表示該模塊的標識,爲可選參數。
dependencies 是一個字符串 Array,表示該模塊依賴的其他所有模塊標識,模塊依賴必須在真正執行具體的 factory 方法前解決,這些依賴對象加載執行以後的返回值,可以以默認的順序作爲 factory 方法的參數。dependencies 也是可選參數,當用戶不提供該參數時,實現 AMD 的框架應提供默認值爲 [“require”,”exports”,“module”]。
factory 是一個用於執行改模塊的方法,它可以使用前面 dependencies 裏聲明的其他依賴模塊的返回值作爲參數,若該方法有返回值,當該模塊被其他模塊依賴時,返回值就是該模塊的輸出。
CommonJS 在規範中並沒有詳細規定其他的方法,一些主要的 AMD 框架如 RequireJS、curl、bdload 等都實現了 define 方法,同時各個框架都有自己的補充使得其 API 更實用。
下面:我將舉一個很簡單的require.js的模塊化使用:
首先看我這個demo的文件路徑:
<a href="https://img-blog.csdn.net/20150211115148526"></a>
模塊一:student.js
define(function(){
return {
createStudent: function(name,gender){
return {
name: name,
gender: gender
};
}
};
});
模塊二:class.js
define(function(){
var allStudents = [];
return {
classID: '001',
department: 'computer',
addToClass: function(student) {
allStudents.push(student);
},
getClassSize: function() {
return allStudent.length;
}
};
});
模塊三: manager.js 依賴模塊一、二
define(['student','class'],function(student,cls){
return {
addNewStudent: function(name,gender) {
cls.addToClass(student.createStudent(name,gender));
},
getClassSize: function() {
return cls.getClassSize();
}
};
});
測試:main.js
// require(['student','class'],function(student,cls){
// cls.addToClass(student.createStudent('jack','male'));
// cls.addToClass(student.createStudent('lucy','female'));
// console.log(cls.getClassSize());
// });
require(['manager'],function(m){
m.addNewStudent('jack','male');
m.addNewStudent('lucy','female');
console.log(m.getClassSize());
});
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<script type="text/javascript" src="require.js" data-main="main"></script>/**記得引進require.js**/
<title>require學習</title>
</head>
<body>
<p>請查看控制檯</p>
</body>
</html>
這是我自己學習AMD,require.js的開始,希望跟大家一起交流學習,共同進步!