【面试系列】之一:关于Cmd和Amd

之一:关于Cmd和Amd

为何想起来作这样一个专题呢,答案应该是为了勉励面试笔试秋招中的本身吧!
并且也是为了和我同样的你。javascript

1.开篇

我叫王彬,如今是百度首页业务部(原网页搜团队索部FE前端)的实习FE,
两天前我得知我所在的部门只有两个hc,并且要分给策略rd,
这就意味着我要面临千军万马过独木桥的“秋招”
可能个人描述有点夸张,可是此时此刻的真的是这么感受的。
我以为以我如今的水平,可能不会有一家大公司要我,因此我发自心里的厌恶秋招!
可是必须面对!
一块儿努力吧,但愿本身能够一直写下去。
所写的文章确定有不完善的地方,但愿看的朋友能够指正,我会虚心接受一切声音。
好,言归正传!
我今天要写的是关于Amd和Cmdhtml

首先来看这个http://www.zhihu.com/question...
玉伯知乎上的回答前端

说到Amd和Cmd,你可能和我同样,最早想到的就是require.js以及sea.js
由于二者分别的是Amd和Cmd的表明
在开始深刻了解Amd以及Cmd以前,我和你们同样,只是知道这都是js模块化加载的工具
至于模块化加载的好处天然没必要多说,用过的应该都懂
那么咱们就从require.js和sea.js蔓延开来说讲Amd和Cmdjava

2.Amd的表明require.js

Amd是指Asynchronous Module Definition,异步的模块加载机制。是在推广require.js时对模块规范化产出。
node

如下的内容引自阮一峰老师的博客http://www.ruanyifeng.com/blo...程序员

要说Amd就要先从Common.js提及。面试

2009年,美国程序员Ryan Dahl创造了node.js项目,将javascript语言用于服务器端编程。
node.js的模块系统,就是参照CommonJS规范实现的。在CommonJS中,有一个全局性方法require(),用于加载模块。假定有一个数学模块math.js,就能够像下面这样加载。算法

var math = require('math');
math.add(2,3); // 5

有了服务器端模块之后,很天然地,你们就想要客户端模块。并且最好二者可以兼容,一个模块不用修改,在服务器和浏览器均可以运行。
可是,因为一个重大的局限,使得CommonJS规范不适用于浏览器环境。仍是上一节的代码,若是在浏览器中运行,会有一个很大的问题,你能看出来吗?编程

第二行math.add(2,3),在第一行require('math')以后运行,所以必须等math.js加载完成。也就是说,若是加载时间很长,整个应用就会停在那里等。数组

这对服务器端不是一个问题,由于全部的模块都存放在本地硬盘,能够同步加载完成,等待时间就是硬盘的读取时间。

可是,对于浏览器,这倒是一个大问题,由于模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于"假死"状态。

所以,浏览器端的模块,不能采用"同步加载"(synchronous),只能采用"异步加载"(asynchronous)。这就是AMD规范诞生的背景。

下面具体的用法,看一下下面的举例(具体详细配置以及使用方法请你们查看require.js官方文档):

//经过数组引入依赖 ,回调函数经过形参传入依赖 
define(['someModule1', ‘someModule2’], function (someModule1, someModule2) { 

    function foo () { 
        // something 
        someModule1.test(); 
    } 

    return {foo: foo} 
});

AMD规范容许输出模块兼容CommonJS规范,这时define方法以下:

define(function (require, exports, module) { 
     
    var reqModule = require("./someModule"); 
    requModule.test(); 
     
    exports.asplode = function () { 
        //something
    } 
});

可是值得注意的是:
仍然按照这种写法,加载的模块仍会被提早读取且加载(记住是读取且加载,后面有用),
与下面的这种写法效果同样!

define(['./someModule'], function (require, exports, module, reqModule) { 

    requModule.test(); 
     
    exports.asplode = function () { 
        // something
    } 
});

所以咱们能够得出结论:
1.Amd推崇的是依赖前置
2.Amd对加载的模块是提早读取并加载

3. Cmd表明的sea.js

Cmd是指Common Module Definition,异步的模块加载机制。是在推广sea.js时对模块规范化产出。
说到Cmd,你们千万不要望文生义,认为这和Common.js在服务器端的加载方式相同,其实并不同。
其实Cmd更像是Amd和Common.js的升级版,结合了二者的优势。

Common.js能够作到当须要这个模块时,再读取并加载。
Amd能够作到避免Common.js的 “临时读取并加载文件”,它是提早读取并加载。

而Cmd能够作到的是,“提早读取文件,但在须要再加载”,这样能够避免浏览器临时加载文件的假死,也能够避免提早加载引发的逻辑问题。

具体的逻辑问题指什么呢?咱们来看这篇图文并茂的讲解:

请戳:https://www.douban.com/note/2...

请仔细看,若是有点懵的话,像我同样,再看两遍。

因此你们叫sea.js懒加载,也就是 “as lazy as possible”,若是你面试的时候说出这句话,面试官必定对你另眼相看。这也是Cmd的标志!
懒加载能够很好的做为判别Amd和Cmd的方法哈!

所以咱们能够总结出:
1.Cmd推崇的是就近依赖
2.Cmd对加载的模块是提早读取并不加载,而是在须要时加载

4. 总结

我在百度实习时接触到过一个框架,用于百度PC首页和PAD首页的模块化开发。
这个框架是F框架(移动端因为性能优化的要求使用的是B框架,esl.js),感兴趣的朋友能够深刻了解一下。

F框架有一个特色,

F.module('hello', function () {
    // require('world');
    // do something...
})

若是代码这么写,虽然require('world')被注释掉了
可是world这个模块依然会被加载,你们知道为何吗?

答案是:由于F框架遵循的是Amd规范,会正则匹配factory也就是模块的主体函数中的require字段,一但匹配到就会进行前置读取并加载。
因此会出现这种现象。

这个例子但愿能够帮助你们理解。
最后再看遍文章开头提到的玉伯大神的问答 http://www.zhihu.com/question... 加深理解

文章的内容并非所有原创,
我在网上借鉴了许多老师的经验

http://www.zhihu.com/question...
https://www.douban.com/note/2...
http://zccst.iteye.com/blog/2...
http://www.ruanyifeng.com/blo...

感谢以上全部老师的智慧结晶!

下一次想和你们聊聊js原型那些事,争取立刻更新!对啦,你们有没有什么复习数据结构与算法的好办法,但愿数据结构与算法大神指点明津!

相关文章
相关标签/搜索