当说到一个应用是模块化的,意思是说它是由一系列耦合度很低、有明确功能的模块所组成。松耦合经过尽量移除依赖(by removing dependencies)使Apps维护起来更方便;javascript
这里介绍三种书写模块化javascript的方法:AMD, CommonJS, Harmony(proposals for the next version of javascript);php
序:实现模块化的基本方法就是使用script loaders(推荐RequireJS和curl.js)。从产品发布的角度来看,使用优化工具(如RequireJS optimizer)将scripts链接到一块是不错的选择。页面加载后的动态脚本加载也可能会有用,RequireJS也支持。html
AMD format的主要目就是为developer提供javascript模块化变成的方案;跟CommonJS的主要区别是:AMD是为browser端而设计;CommonJS面向的是server端;java
AMD和CommonJS的简单区别(可能不彻底):node
1)scoping:browser中没法对js代码进行彻底隔离,只能在function中定义变量使其不会在global中出现,这样很容易致使错误出现: var a=b=0;web
AMD不能很好的解决这个问题。相反,AMD支持将external resource引入local function scope,进而实现local scoping;编程
CJS是干净的server端环境,如node,没有global scope;api
2)Distance:对浏览器来讲,不少资源都是remote的,虽然资源可能被cache到本地,可请求/得到资源老是费时间的;若是要执行的function在另外一个文件中,咱们就没法知道这个文件是否已经被load进来或者还要花数秒去得到这个文件;若是不知道function是否已经被定义,那么就不能擅自调用它;浏览器
CJS解决这个问题的方法是:假设全部请求的资源都在本地,或者至少能够在毫秒级甚至微秒级时间内请求到;app
3)Asynchrony:上边所说的distance问题形成的直接结果是,须要异步执行task。浏览器在单独线程内执行javascript,若是此线程在等待远程资源,此时啥也不会执行,用户感受浏览器没反应了。
解决这个问题的方法是,当资源被准备好了就执行提取初始化操做和请求回调函数操做(callback function);
Node主要经过事件驱动编程模型来实现异步;
简单地说,CJS同步提取module resource,由于资源在微秒级的时间内能够到达,不须要异步!
AMD:
// define() is a necessary wrapper. define( // dependencies are specified in advance.指定依赖模块
['pkgA/modA', 'pkgA/modB', 'pkgZ/modC'], // the module is declared within a definition function. // dependencies are mapped into function parameters. function (modA, modB, modC) { // inside here is the module's code. // the module is exported to the outside world via the // the definition function's returned value. return modC ? modA : modB; } );
CommonJS:
// there is no explicit wrapper, we just write the module's code. // this is not global scope! the scope is limited to this file only. // "free" variables (`require`, `module`, and `exports`) are // declared to help us define our module and fetch resources. // dependencies are specified as needed var modC = require('pkgZ/modC'); // the module is exported by decorating the `exports` free variable. exports.foo = modC ? require('pkgA/modA') : require('pkgA/modB');
___________________________________________AMD____________________________________________
|AMD经过将module定义在definition function里来处理异步,definition function其实是一个回调函数。 |
|当全部依赖module都加载完毕且起源均可用后,它才被调用; |
|________________________________________________________________________________________|
___________________________________________CJS____________________________________________
|CJS尽量快地执行module代码,只有须要的时候才load/execute the module dependencies; |
|上边的示例中,'pkgA/modA'和'pkgB/modB'只加载执行其中一个;当不必加载执行全部modules的状况下,CJS |
|比AMD效率高; |
|________________________________________________________________________________________|
哪一个更给力?在浏览器端,咱们要么提早提取依赖模块,要么同步提取;AMD有两个plugin,'has.js'和'has!',这俩能够解决大部分此类问题,但不可能解决全部的状况;
至于代码多少,上边的例子中CJS很明显少一些;
答案是:neither!两个都会用到。
1.AMD在browser中使用会有不少好处,究竟有啥好处,这里。
2.AMD和CJS会共存很长时间,很长!能作的是:
1)用CJS写server端执行的module;
2)用AMD写能够利用其客户端友好功能的module;