昨天小颖分享了一篇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 的缘由是同样的。小颖这样的解释能明白吗?