JavaScript进阶(十二):JS 模块化编程规范-CommonJS、AMD、CMD(1)

总结
  • 对于框架原理只能说个大概,真的深入某一部分具体的代码和实现方式就只能写出一个框架,许多细节注意不到。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 算法方面还是很薄弱,好在面试官都很和蔼可亲,擅长发现人的美哈哈哈…(最好多刷一刷,不然影响你的工资和成功率???)

  • 在投递简历之前,最好通过各种渠道找到公司内部的人,先提前了解业务,也可以帮助后期优秀 offer 的决策。

  • 要勇于说不,对于某些 offer 待遇不满意、业务不喜欢,应该相信自己,不要因为当下没有更好的 offer 而投降,一份工作短则一年长则 N 年,为了幸福生活要慎重选择!!!

第一次跳槽十分忐忑不安,和没毕业的时候开始找工作是一样的感受,真的要相信自己,有条不紊的进行。如果有我能帮忙的地方欢迎随时找我,比如简历修改、内推、最起码,可以把烦心事说一说,人嘛都会有苦恼的~

祝大家都有美好的未来,拿下满意的 offer。

})


加载方法如下:



// main.js
require([‘math’], function(math) {
alert(math.add(1, 1));
})


如果`math`模块还依赖其他模块,写法如下:



// math.js
define([‘dependenceModule’], function(dependenceModule) {
// …
})


当`require()`函数加载`math`模块的时候,就会先加载`dependenceModule`模块。当有多个依赖时,就将所有的依赖都写在`define()`函数第一个参数数组中,所以说`AMD`是依赖前置的。这不同于`CMD`规范,它是依赖就近的。  
 CMD


### 三、CMD-同步模块定义


`CMD` 即`Common Module Definition`通用模块定义,是`SeaJS`在推广过程中对模块定义的规范化产出,是一个同步模块定义,是`SeaJS`的一个标准,`SeaJS`是`CMD`概念的一个实现,`SeaJS`是淘宝团队玉伯提供的一个模块开发的`js`框架。`CMD`规范是国内发展出来的,就像`AMD`有个`requireJS`,`CMD`有个浏览器的实现`SeaJS`,`SeaJS`要解决的问题和`requireJS`一样,只不过在模块定义方式和模块加载(可以说运行、解析)时机上有所不同。


`CMD` 通过`define()`定义,没有依赖前置,通过`require`加载`jQuery`插件,`CMD`是依赖就近,在什么地方使用到插件就在什么地方`require`该插件,即用即返,这是一个同步的概念。


在 `CMD` 规范中,一个模块就是一个文件。代码的书写格式如下:



define(function(require, exports, module) {
// 模块代码
});


其中,



> 
> * `require`是可以把其他模块导入进来的一个参数;
> * `exports`是可以把模块内的一些属性和方法导出的;
> * `module` 是一个对象,上面存储了与当前模块相关联的一些属性和方法。
> 
> 
> 


`AMD`是依赖关系前置,在定义模块的时候就要声明其依赖的模块;  
 `CMD`是按需加载依赖就近,只有在用到某个模块的时候再去`require`,示例代码如下:



// 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()

})


### 四、CommonJS 规范


`CommonJS`规范是通过`module.exports`定义的,在前端浏览器里面并不支持`module.exports`,通过`node.js`后端使用。`Nodejs`端使用`CommonJS`规范,前端浏览器一般使用`AMD`、`CMD`、`ES6`等定义模块化开发规范。


`CommonJS`的终极目标是提供一个类似`Python`,`Ruby`和`Java`的标准库。这样的话,开发者可以使用`CommonJS API`编写应用程序,然后这些应用就可以运行在不同的`JavaScript`解释器和不同的主机环境中。


在兼容`CommonJS`的系统中,你可以使用`JavaScript`开发以下程序:



> 
> 1. 服务器端`JavaScript`应用程序;
> 2. 命令行工具;
> 3. 图形界面应用程序;
> 4. 混合应用程序(如,Titanium或Adobe AIR);
> 
> 
> 


2009年,美国程序员Ryan Dahl创造了`node.js`项目,将`javascript`语言用于服务器端编程。这标志"`Javascript`模块化编程"正式诞生。`NodeJS`是`CommonJS`规范的实现,`webpack` 也是以`CommonJS`的形式来书写。


`node.js`的模块系统,就是参照`CommonJS`规范实现的。在`CommonJS`中,有一个全局性方法`require()`,用于加载模块。假定有一个数学模块`math.js`,就可以像下面这样加载。



var math = require(‘math’);


然后,就可以调用模块提供的方法:



var math = require(‘math’);

math.add(2,3); // 5


`CommonJS`定义的模块分为:**模块引用(require)**、 **模块定义(exports)**、**模块标识(module)**。  
 其中,



> 
> * `require()`用来引入外部模块;
> * `exports`对象用于导出当前模块的方法或变量,唯一的导出口;
> * `module`对象就代表模块本身。
> 
> 
> 


虽说`NodeJS`遵循`CommonJS`的规范,但是相比也是做了一些取舍,添了一些新东西的。


`NPM`作为`Node`包管理器,同样遵循`CommonJS`规范。


下面讲讲`commonJS`的原理以及简易实现:


1、原理  
 浏览器不兼容`CommonJS`的根本原因,在于缺少四个`Node.js`环境变量。



module
exports
require
global


只要能够提供这四个变量,浏览器就能加载 `CommonJS` 模块。


下面是一个简单的示例。



var module = {
exports: {}
};

(function(module, exports) {
exports.multiply = function (n) { return n * 1000 };
}(module, module.exports))

var f = module.exports.multiply;
f(5) // 5000


上面代码向一个立即执行函数提供 module 和 exports 两个外部变量,模块就放在这个立即执行函数里面。模块的输出值放在 module.exports 之中,这样就实现了模块的加载。


2、Browserify 的实现  
 `Browserify` 是目前最常用的 `CommonJS` 格式转换工具。


请看一个例子,`main.js` 模块加载 `foo.js` 模块。



// foo.js
module.exports = function(x) {
console.log(x);
};

// main.js
var foo = require(“./foo”);
foo(“Hi”);


使用下面的命令,就能将`main.js`转为浏览器可用的格式。



$ browserify main.js > compiled.js


其中,`Browserify`到底做了什么?安装一下`browser-unpack`,就清楚了。



$ npm install browser-unpack -g


然后,将前面生成的compile.js解包。



$ browser-unpack < compiled.js



[
{
“id”:1,
“source”:“module.exports = function(x) {\n console.log(x);\n};”,
“deps”:{}
},
{
“id”:2,
“source”:“var foo = require(”./foo");\nfoo(“Hi”);“,
“deps”:{”./foo":1},
“entry”:true
}
]


可以看到,`browerify` 将所有模块放入一个数组,`id` 属性是模块的编号,`source` 属性是模块的源码,`deps` 属性是模块的依赖。


因为 `main.js` 里面加载了 `foo.js`,所以 `deps` 属性就指定 `./foo` 对应1号模块。执行的时候,浏览器遇到 `require('./foo')` 语句,就自动执行1号模块的 `source` 属性,并将执行后的 `module.exports` 属性值输出。


### 五、ES6


有关`es6`模块特性,强烈推荐阮一峰老师的:[ECMAScript 6 入门 - Module 的语法](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)专栏。


要说 `ES6` 模块特性,那么就先说说 `ES6` 模块跟 `CommonJS` 模块的不同之处。



> 
> * `ES6` 模块输出的是值的引用,输出接口动态绑定,而 `CommonJS` 输出的是值的拷贝;
> * `ES6` 模块编译时执行,而 `CommonJS` 模块总是在运行时加载。
> 
> 
> 


`CommonJS` 模块输出的是值的拷贝(原始值的拷贝),也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。



// a.js
var b = require(‘./b’);

HTTP

  • HTTP 报文结构是怎样的?

  • HTTP有哪些请求方法?

  • GET 和 POST 有什么区别?

  • 如何理解 URI?

  • 如何理解 HTTP 状态码?

  • 简要概括一下 HTTP 的特点?HTTP 有哪些缺点?

  • 对 Accept 系列字段了解多少?

  • 对于定长和不定长的数据,HTTP 是怎么传输的?

  • HTTP 如何处理大文件的传输?

  • HTTP 中如何处理表单数据的提交?

  • HTTP1.1 如何解决 HTTP 的队头阻塞问题?

  • 对 Cookie 了解多少?

  • 如何理解 HTTP 代理?

  • 如何理解 HTTP 缓存及缓存代理?

  • 为什么产生代理缓存?

  • 源服务器的缓存控制

  • 客户端的缓存控制

  • 什么是跨域?浏览器如何拦截响应?如何解决?

    开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 10
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值