疑問:爲何會出現CMD規範?爲何會出現sea.js,它到底解決了什麼問題?html
答案:CMD規範是國內發展起來的,和AMD規範相似,AMD規範有一個require.js的實現,CMD也有一個叫sea.js的實現,這就是他們出現的背景。api
至於解決了什麼問題?咱們能夠暫且認爲他和AMD解決的問題是同樣的, 1: 瀏覽器中js文件的異步加載,避免的js文件的阻塞問題 2: 定義了模塊之間如何相互依賴,更好的維護文件代碼。瀏覽器
這裏就冒出了一個疑問?CMD規範和AMD規範的做用不是同樣嘛,那他倆有什麼區別呢?稍後詳述bash
和AMD規範與require.js的關係同樣,CMD是一個規範,sea.js是規範的具體實現。異步
//index.html: 引入sea.js和主入口文件main.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="./sea.js"></script>
<script src="./main.js"></script>
</body>
</html>
複製代碼
//main.js ,這裏引入了三個模塊文件,
seajs.use(['./lib/a.js', './lib/b.js', './lib/c.js'], function (a, b, c) {
console.log(a);//{name: 1}
console.log(b);//{name: 2}
console.log(c);//{name: 3}
});
複製代碼
//定義模塊文件
//a.js
define({
name: 1
});
//b.js
define({
name: 2
});
//c.js
define({
name: 3
});
複製代碼
思想相似,解決的問題都同樣, 都是異步加載模塊,同時更好的定義了模塊之間如何去依賴。函數
1: 模塊定義都是採用define()方法,模塊引入的api全部不一樣,可是思想一致,第一個參數表示引入的模塊路徑,第二個參數是回調函數,表示全部模塊所有加載完成之後,所調用的函數。性能
AMD規範:採用define去定義模塊,採用require(['模塊1','模塊2'], function() {}) 去引入模塊 CMD規範:採用define去定義模塊,採用seajs.use('模塊1','模塊2'], fucntion () {}) 去引入模塊ui
2: 模塊加載的時機不一樣spa
AMD規範:依賴前置:即在模塊中引入其餘模塊時,必須提早聲明好要引入的模塊
//main.js模塊
define(['./a', './b'], function(a, b) {
a.doSomething();
b.doSomething();
});
說明:
咱們分析一下上面的代碼:
瀏覽器在加載main.js模塊時,首先看到了聲明瞭a.js和b.js模塊,因此會首先加載這兩個模塊,加載完成之後,再執行回調函數中代碼。
複製代碼
CMD規範:依賴就近:即在模塊中不須要提起聲明要引入的模塊,寫代碼哪裏用到其餘模塊,就在哪裏直接引入模塊。
//main.js模塊
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
var b = require('./b')
b.doSomething()
})
說明:
咱們再來分析一下用cmd規範實現的這段代碼:
瀏覽器在加載main.js模塊時,它會首先遍歷整個文件中,而後找到全部帶require關鍵字的代碼,而且加載其對應的模塊,因此相對於AMD規範直提早聲明要引用的 模塊(依賴前置)而言,
CMD規範 則須要 遍歷 整個文件,才能夠找到須要加載哪些模塊 (這一步遍歷整個文件找requuire關鍵字就犧牲了性能,帶了方便就是書寫的方便,
咱們不用考慮提早引入哪些模塊,只須要直接寫代碼,而後寫着寫着,發現這段代碼須要引入其餘模塊,而後直接在此處引入其餘模塊便可)
複製代碼