AMD、CMD、requirejs

题目1: 为什么要使用模块化?

模块化可以使代码低耦合,功能模块直接不相互影响。

1.可维护性:根据定义,每个模块都是独立的。良好设计的模块会尽量与外部的代码撇清关系,以便于独立对其进行改进和维护。维护一个独立的模块比起一团凌乱的代码来说要轻松很多。
2.命名空间:在JavaScript中,最高级别的函数外定义的变量都是全局变量(这意味着所有人都可以访问到它们)。也正因如此,当一些无关的代码碰巧使用到同名变量的时候,我们就会遇到“命名空间污染”的问题。
3.提高代码的可复用性。
4.进行依赖管理。

题目2: CMD、AMD、CommonJS 规范分别指什么?有哪些应用

Asynchronous Module Definition (AMD)/(异步模块定义)

它推崇依赖前置,采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。
特点/缺点:

  • 依赖前置,需要在定义的时候,写好需要的依赖。
  • 多个JS有依赖关系。被依赖的JS需要早于依赖它的文件提前加入。
  • JS加载的时候,页面会停止渲染。加载的文件越多。页面失去响应的时间越长。

应用:Reauire.js

//定义模块:
define(id ?, dependencies?, function)
-----------------------------------------------
//id:可选参数,用来定义模块标识。如果没有写,就用文件名。
//denpendencies:当前的模块依赖的模块,数组形式。
//function:执行的函数
//加载模块
require([dependencies], function)
//---------------------------------------------
//dependencies:当前模块需要的依赖的模块。
//function:回调函数,在模块加载完了后,会被执行。
//require是异步执行。在依赖模块没有被加载完。是不会执行回调函数的。同时浏览器不会失去响应。

Common Module Definition ——(CMD)

通用模块定义,是一种模块定义方式和模块加载方式的规范

  • 依赖就近,需要的时候再引入这个依赖项,用的时候再require。
  • 推崇一个文件一个模块,所以经常将文件名作为模块id
  • 因推崇依赖就近,所以一般不在define的参数中写依赖,在factory中写。

应用:sea.js

define(function(require,exports,module){})
//require:获取其他的模块提供的接口。
//exports:对外提供模块的接口。
//module是个对象,上面存储了与当前模块相关的属性和方法
//定义模块
define(function(require, exports, module){
  var $ = require('jquery.js')
  $('div').removeClass('active')
})

 //加载模块
seajs.use(['myModule.js'], function(my){
  
})

AMD与CMD的差别是:AMD是首先加载所有模块,再执行,而CMD是按需加载。AMD依赖前置,js可以方便知道依赖模块是谁,立即加载;而CMD就近依赖,需要使用把模块变为字符串解析一遍才知道依赖了那些模块,这也是很多人诟病CMD的一点,牺牲性能来带来开发的便利性,实际上解析模块用的时间短到可以忽略。如今requireJS和seaJS都已经是过去时,webpack和Browserify成为主流

CommonJS

  • 一个单独的文件就是一个模块,每个模块都是一个单独的作用域
    在模块内部定义的变量,无法被其他模块读取,除非定义为global对象的属性
  • 模块输出:模块只有一个出口,module.exports对象,我们需要把模块希望输出的内容放入该对象
  • 加载模块:加载模块使用require方法,该方法读取一个文件并执行,返回 文件内部的module.exports对象,如果请求的模块不能返回,那么”require”必须抛出一个错误。
//定义模块 myModule.js
var name =  'mamba'

function printName(){
  console.log(name)
}

function printFullName(firstName){
    console.log(firstName + name);
}

//输出模块
module.exports = {
    printName: printName,
    printFullName: printFullName
}

//加载模块
var nameModule = require('./myModule.js') //不同的实现对require时的路径有不同要求,一般情况可以省略js拓展名,可以使用相对路径,也可以使用绝对路径,甚至可以省略路径直接使用模块名(前提是该模块是系统内置模块)

//使用模块
nameModule.printName();

应用:因为require是同步的,所以主要在服务器端使用
浏览器端加载JavaScript是异步的,所以传统的CommonJS在浏览器环境中无法正常加载。

你可能感兴趣的:(AMD、CMD、requirejs)