昨天小穎分享了一篇require.js入門 ,今天小穎發現了一個很鬱悶的問題,但願大神們幫小穎解釋下究竟是什麼原理才能出現如下的現象,其實小穎昨天也有問過園友裏的一位帥鍋,只是他解釋的小穎沒太明白。嘻嘻因此寫出來想經過博客園這個平臺裏集思廣益,解決這個疑惑。css
好啦咱們一塊兒來看看這個讓小穎頭疼的問題:html
demo目錄:jquery
代碼來啦:數組
公用的文件index.html和ceshi.jsapp
index.html異步
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>require.js小demo</title> <!-- 加載require.js文件,也可能形成網頁失去響應。解決辦法有兩個,一個是把它放在網頁底部加載,另外一個是寫成下面這樣: --> <!-- <script src="js/require.js" defer async="true" ></script> --> <!--async屬性代表這個文件須要異步加載,避免網頁失去響應。IE不支持這個屬性,只支持defer,因此把defer也寫上。 --> <!-- 加載require.js之後,下一步就要加載咱們本身的代碼了。假定咱們本身的代碼文件是main.js,也放在js目錄下面。只須要寫成下面這樣就好了: --> <!-- <script src="js/require.js" data-main="src/main.js"></script> --> <script defer async="true" data-main="app" src="js/require.js"></script> </head> <body> <div class="div-index">哈嘍</div> </body> </html>
ceshi.jsasync
define(function(require) { var ad = function() { return 'aaa'; }; return { ad: ad } });
有變化的文件哦:函數
app.jsrequirejs
requirejs.config({ baseUrl: 'js/lib', paths: { cs:'ceshi', jquery: '../jquery' } }); require(['main', 'jquery'], function(mains, jq) { console.log(mains.add(2, 5)); console.log(jq); });
main.jspost
define(['cs'],function(ceshi) { console.log(ceshi.ad()); var add = function(x, y) { return x + y; }; return { add: add } });
結果:
當小穎在app.js中加載jquery的時候,將 paths: { cs:'ceshi', jquery: '../jquery' }改成:paths: { cs:'ceshi', jq: '../jquery' }時:
app.js
requirejs.config({
baseUrl: 'js/lib',
paths: {
cs:'ceshi',
jq: '../jquery'
}
});
require(['main', 'jq'], function(mains, jqs) {
console.log(mains.add(2, 5));
console.log(jqs);
console.log($);
});
結果就變成了:
問題:小穎想問下爲何將在paths中在加載 ceshi.js 時,給其命名爲 cs,在main.js中就能正常調到,而將 jquery 改爲 jq 就到不到了呢?可是用jquery的 $ 符號卻能調到這又是爲何?
小穎在paths中不加載jquery.js和ceshi.js在用的時候再加載:
app.js
requirejs.config({ baseUrl: 'js/lib', paths: { // cs:'ceshi', // jq: '../jquery' } }); require(['main'], function(mains) { console.log(mains.add(2, 5)); });
main.js
define(['../jquery','ceshi'],function(jq,cs) {
console.log(jq);
console.log($);
console.log(cs.ad());
var add = function(x, y) {
return x + y;
};
return {
add: add
}
});
結果:
問題:像上面那種加載方式加載jquery.js,爲何加載了 ceshi.JS ,後用回調函數中的別名 cs 卻能調到,可是 jquery 用 jq 卻調不到,可是用 $ 符號卻能調到?
在上面的有問題的兩種狀況下,你們都發現只有給jquery從新起一個加載的名字,在打印這個別名時有問題,但按照AMD模塊的寫法寫的ceshi.js起別名就是ok的,因此小穎以爲問題不在require.js上,問題應該出自jquery自己,小穎看了jquery源碼後發現:
當小穎將define中的 jquery 刪除 時,以上兩種狀況就ok啦:
緣由:
define(name,[] , callback); 這個name能夠省掉,默認是文件名稱;固然也能夠自定義,一旦咱們定義了name,根據源代碼咱們能夠發現define函數內部其實就是把這個name以及依賴模塊、回調函數做爲一個對象存儲在全局的數組當中,也就是 defQueue.push([name,deps,callback]);那麼這個name就是這個組件註冊的的ID!
雖然小穎雖然在paths中將jquery起名爲 jq,可是jquery自身已經經過define(name,[] , callback);命名成 jquery了,因此用後面再用jq就調不到了。
第一種狀況:
app.js
requirejs.config({
baseUrl: 'js/lib',
paths: {
cs:'ceshi',
jq: '../jquery'
}
});
require(['main', 'jq'], function(mains, jqs) {
console.log(mains.add(2, 5));
console.log(jqs);
console.log(123+$);
});
小穎將jquery.js中的define裏面的參數的 jquery 刪除 時結果:
第二種狀況:
app.js
requirejs.config({ baseUrl: 'js/lib', paths: { // cs:'ceshi', // jq: '../jquery' } }); require(['main'], function(mains) { console.log(mains.add(2, 5)); });
main.js
define(['../jquery','ceshi'],function(jq,cs) { console.log(123+jq); console.log($); console.log(cs.ad()); var add = function(x, y) { return x + y; }; return { add: add } });
小穎將jquery.js中的define裏面的參數的 jquery 刪除 時結果:
先看看目錄吧:
index.html我就不給你們寫出來了,那個你們在上面能夠複製下來把 data-main 和 src 的值一修改就行了。
app.js
requirejs.config({ baseUrl: 'js/lib', paths: { css:'ceshi', jqy: 'jquery' } }); require(['../app/main'], function(mains) { console.log(mains.add(2, 5)); });
從上面的目錄圖片能夠看出,小穎將 ceshi.js 、jquery.js 、require.js 這三個js放在同一個目錄下,js下的lib下,在這個demo中,小穎把jquery文件define裏面的參數的 jquery 刪除 已經刪除了,因此小穎能夠給其任意起id名啦。此次叫的是 jqy。
lib下的ceshi.js
define('css',[],function(require) { console.log('個人文件名叫ceshi(曾用名),個人實際叫css(如今的名字)'); var ad = function() { return 'hello world'; }; return { ad: ad } });
你們仔細看下上面代碼中的第一行,小穎在ceshi.js中經過 define('css',[],function(require) {});已經將ceshi.js命名爲 css 因此小穎在 app.js中加載ceshi.js時給的id是css,這樣才能真正的加載到ceshi.js.
js/app/main.js
define(['jqy','css'],function(jq,cs) { console.log(123+jq); console.log(cs.ad()); var add = function(x, y) { return x + y; }; return { add: add } });
結果:
若是小穎將app.js中加載ceshi.js的id改爲與ceshi.js中命名的名字不同的話:
requirejs.config({ baseUrl: 'js/lib', paths: { cs:'ceshi', jqy: 'jquery' } }); require(['../app/main'], function(mains) { console.log(mains.add(2, 5)); });
main.js
define(['jqy','cs'],function(jq,cs) { console.log(jq); console.log(cs); console.log(cs.ad()); var add = function(x, y) { return x + y; }; return { add: add } });
結果:
其實這時cs是 undefined 和上面小穎提的jquery是 undefined 的緣由是同樣的。小穎這樣的解釋能明白嗎?