1.为什么要使用模块化?
在模块化还未规范化之前,有三种模仿模块化的方法,分别是函数声明,对象返回,和立即执行函数封装,之后才有模块化的规范,在ES6中,也对“类”和“模块”有定义,不过要主流浏览器都支持时才能广泛使用。之所以使用模块化是因为:
解决命名冲突;
方便依赖性管理;
提高代码的维护性和可读性;
每个模块都是单独文件,解耦提高代码复用性;
2.CMD、AMD、CommonJS 规范分别指什么?有哪些应用
- CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。但是,如果是浏览器环境(客户端),要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。
- AMD和CMD最大的区别是对依赖模块的执行时机处理不同,AMD依赖前置,js可以方便知道依赖模块是谁,立即加载;而CMD就近依赖。需要时就写出依赖。
- CMD(Common Module Definition)
语法:
define(id?, deps?, factory)
依赖就近原则,用的时候require。所以一般不在define中写依赖,在factory函数中写。
factory(require,exports,module){
}
// require:模板入口
//exports:对象,向外提供模板出口
缺点:CMD加载完某个依赖模块后并不执行,遇到require时执行对应模块,有延迟速度不如AMD快。
优点:执行顺序和书写顺序,按需加载对应模块。
- AMD(Asynchronous Module Definition)
它是一个在浏览器端模块化开发的规范,由于不是JavaScript原生支持,使用AMD规范进行页面开发需要用到对应的库函数(RequireJS),实际上AMD 是 RequireJS 在推广过程中对模块定义的规范化的产出。
define是require.JS定义的全局变量,它是一个函数。语法:
define(id?, dependencies?, factory);
//id可选参数,用来定义模块的标识,如果没有提供该参数,为脚本文件名
//dependencies是一个当前模块依赖的模块名称数组
//factory模块初始化要执行的函数或对象。若为回调函数,则执行一次,若为对象,则该对象为输出值。
优点:AMD中require()采用异步加载,这样浏览器不会失去响应,它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。
缺点:依赖提前声明有时候并不是很好,而且都无法与同步模块规范保持一致,会出现执行顺序和书写顺序不一致的情况。
模块依赖声明方式:
define(['./a', './b'], function (a, b) {
// 模块 a 和 b 在这里就都执行好并可用了
})
- CommonJS
var a = require('./a');
a.readfile();
CommonJS模块的特点:
- 所有代码都运行在模块作用域,不会污染全局作用域。
- 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
- 模块加载的顺序,按照其在代码中出现的顺序。
网友评论