对于amd还有cmd的描述,我不太想累赘的去讲,就直接讲讲大一点的区别吧,先讲解一些实用性方面的,比如,
在加载方面,amd是预加载,但是,他也是预运行,所以会很费时间,但是在后面要运行到某个js文件的时候,因为先运行过了,所以会特别快,
相同的,在cmd上,他也是预先加载,但是不预先运行,这造成的现象是人们会觉得他比较快,但是每次运行到一个js文件的时候,由于之前没有运行过,所以可能会出现卡顿现象,就相当于一次性,注意,运行完后,下回不会说之前运行过一次而速度加快。cmd与amd大致上就是这种区别,就相当于“CMD的API推崇职责单一,没有全局的require
AMD的API默认是一个当多个用:比如require有全局的和局部的“。
下面是知乎玉伯的解说:
链接:https://www.zhihu.com/question/20351507/answer/14859415
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。
CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
类似的还有 CommonJS Modules/2.0 规范,是 BravoJS 在推广过程中对模块定义的规范化产出。
还有不少⋯⋯
这些规范的目的都是为了 JavaScript 的模块化开发,特别是在浏览器端的。
目前这些规范的实现都能达成浏览器端模块化开发的目的。
区别:
1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.
2. CMD 推崇依赖就近,AMD 推崇依赖前置。看代码:
// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此处略去 100 行
var b = require('./b') // 依赖可以就近书写
b.doSomething()
// ...
})
// AMD 默认推荐的是
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
a.doSomething()
// 此处略去 100 行
b.doSomething()
...
})
虽然 AMD 也支持 CMD 的写法,同时还支持将 require 作为依赖项传递,但 RequireJS 的作者默认是最喜欢上面的写法,也是官方文档里默认的模块定义写法。
3. AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每个 API 都简单纯粹。
4. 还有一些细节差异,具体看这个规范的定义就好,就不多说了。
另外,SeaJS 和 RequireJS 的差异,可以参考: https://github.com/seajs/seajs/issues/277如果觉得还是一脸萌,没事。实践见真章:
其次,在项目里面实现吧
结构是这样的:
html文件:
//index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="a1.js"></script>
</head>
<body>
<span>这是在加载js后才出现的文字</span>
</body>
</html>
//这是a1.js:
var a1 = (function() {
var m1 = function() { alert("aaaa") };
return {
m1: m1
}
})();
a1.m1();
以上是我们最常用的模块化,接着,一步一步来使用require,首先。导进去:
这样文件就变成这样:
html文件:
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="../lib/require.js" data-main="main.js"></script>
</head>
<body>
<span>alert是否消失了才出现</span>
</body>
</html>
main。js文件:
require操作:require(["../lib/jquery-2.1.1.min.js"],function(a){console.log("jq加载完成")});
(跳得太快了,,,,,先运行下,发现与第一步不同的是。span不会再我们点击alert的确定键后再出现,而是“异步”出现,这就是requirejs异步加载的特征)
其实真正的添加require。js是这样的:
html文件:
<!DOCTYPE html> <html> <head> <script type="text/javascript" src="require.js"></script> <script type="text/javascript"> require(["a"]); </script> </head> <body> <span>body</span> </body> </html>
好了,运行之后会发现除了异步加载,好像也是没什么,接下来我们改成之前用main。js的写法,当然,只是为了规范,要怎样随便你
接下来。我们要拿来实验的是第一步提到的,已经封装好的模块a1.js
改装成这样:
define(["jquery"], function() {
var m1 = function() {
alert("aaaa");
};
var m2 = function() {
$("span").toggle();
console.log("span现在的情况怎么样了呢?");
};
return {
m1: m1,
m2: m2
};
});
define是什么鬼?为什么要用它,还有这种写法又是在干嘛?
当然,你用原先那种写法也是可以的,但是,你会发现会报错,因为没有导入jq,或者说你依赖的jq没有被你所依赖,所以,你需要使用上方的写法,不然怎么倒入你依赖的jq
使用他,我们当然是要去“注册”他,这时候我们的main。js排上用场了。
//main。js:
require.config({
paths: {
"jquery": "../lib/jquery-2.1.1.min",
"a": "a1"
}
});
require(["jquery"]);
require(["a"], function(a) { a.m2();a.m4();
});
看不懂?一步一步来。path,当然是路径了,是使用数组的,所以小心是用逗号,不要用分号了,“”:“”,这种形式,肯定是key:value,所以第一个是名字。第二个的”值域“就是他的路径了
其次。require就是注册了,由于他写法是用数组的,所以无奈我们也只能用数组,哪怕只有一个。可能注意到了,第二个里面有个function。书回掉函数,而且自带参数”a“,a是什么?不说,自己去console。log出来看看。再建议大家去试试如果注册两个,他的回掉函数的参数会怎样,这肯定很有趣
由于jq现在版本对amd支持很好,就不需要使用shim函数,等我找到不支持amd的。再写shim吧,最近时间赶,写的都很草,抱歉