Js模块话编程思想

为什么出现JavaScript的模块化编程思想

原因是在于之前的简单的直接式编程会导致
  • 逻辑混乱
  • 页面复杂
  • 可维护性差
  • 全局变量暴露等问题
所以就有大佬提出了很多的解决方案,其中之一就是JavaScript的模块化思想编程。
那么模块话思想又有什么有点值得我们学习:
  • 解决项目中的全局变量污染的问题。
  • 开发效率高,有利于多人协同开发。
  • 职责单一,方便代码复用和维护 。
  • 解决文件依赖问题,无需关注引用文件的顺序
说到js的模块化就不得不说是谁创建 了这个规范了那就是Commonjs社区的大佬了,他们制定了以下的这些规则
  • 模块的标识应遵循的规则(书写规范)。
  • 定义全局函数require,通过传入模块标识来引入其他模块,执行的结果即为别的模块暴露出来的API。
  • 如果被require函数引入的模块中也包含依赖,那么依次加载这些依赖。
  • 如果引入模块失败,那么require函数应该报一个异常。
  • 模块通过变量exports来向外暴露API,exports只能是一个对象,暴露的API须作为此对象的属性。
那么根据CommonJs规范我们可以知道,每个文件就是一个私有的作用于,是一个独立的模块,这个模块里面的方法,数据,属性全部都是私有的不对外开放的。也就是说外部的模块是无法访问到我们模块内的东西的,除非你将这个变量设置成全局的变量。

举个例子:

const a = 1;
const addA = function(value) {
  return value + a;
}
global.b = 1;

例如上面的代码中我们可以看到使用const定义的a变量和addA方法都是私有的外部是无法访问和使用的,当然b变量使用global定义,就成了全局的变量,此时外部是可以访问的。

那么我们应该怎么将私有的变量开放出去让大家都可以访问呢?

很简单

const addA = function(value) {
  return value + a;
}

module.exports.addA = addA;

像上面的代码这样,module.exports将我们这个方法开放出去,那么外部所有的模块便都能访问到我们这个模块的方法了。

那么外部如何访问呢

var example = require('./addA.js');
console.log(example.addA(1));  //2

外部文件访问这个方法的时候需要使用require方法访问,说白了CommonJS规范解决是解决之前的问题,但却不是一个很好的办法,它还存在着许多的问题,如它只可以在服务端使用,不可以在浏览器端使用,所有这时又出现了另一个规范那就是

AMD规范

AMD叫做异步模块定义。它采用了异步的方式来加载模块,然后在回调函数中执行主逻辑,因此模块的加载不影响它后面的模块的运行。

那么AMD也有自己的规范

  • 用全局函数define来定义模块;
  • id为模块标识,遵从CommonJS Module Identifiers规范
  • dependencies为依赖的模块数组,在factory中需传入形参与之一一对应
  • 如果dependencies的值中有"require"、“exports"或"module”,则与commonjs中的实现保持一致
  • 如果dependencies省略不写,则默认为[“require”, “exports”, “module”],factory中也会默认传入require,exports,module
  • 如果factory为函数,模块对外暴漏API的方法有三种:return任意类型的数据、exports.xxx=xxx、module.exports=xxx
  • 如果factory为对象,则该对象即为模块的返回值

具体分析AMD,我们通过require.js来进行。

require.js是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一,require.js的出现主要是来解决两个问题:

  • 实现JavaScript文件的异步加载,避免网页失去响应。
  • 管理模块的依赖性,管理模块的相互独立性,也就是我们常说的低耦合,这有利于代码的编写与维护。

那么AMD如何使用

define({
    method1: function() {},
    method2: function() {},
});
//等价于
define(function () {
    return {
        method1: function() {},
        method2: function() {},
    }
});

以上是AMD将方法开放出去的方式,使用define

那么外部接收的时候和commonjs一样使用require接收

require([module], callback);

其中两个参数一个module一个callback

module:表示一个数组,里面的成员就是需要加载的模块

callback:就是回调函数

虽然AMD模式的require实现了异步的模块化,但是依然有缺点,就是我们在调用这个方法的时候必须先加载才能调用,而不是想要加载了再调用,不科学,而且会导致初次加载模块的时候会很慢。

这个是就出现了救星了:

CMD 通用模块

CMD称作通用模块定义,由蚂蚁金服的大佬—玉伯提出,实现的js库成为sea.js。

简单的说他就是在AMD的有点上将缺点给摒弃了,也就是说改良了先加载再调用的缺点,sea.js可以实现需要时再加载库,且他还有两大特点:

  • Sea.js 遵循 CMD 规范,可以像 Node.js 一般书写模块代码。
  • 依赖的自动加载、配置的简洁清晰。

在CMD规范中,每一个文件都是自身独立的模块。

模块用define()来定义如:

// 所有模块都通过 define 来定义
define(function(require, exports, module) {

  // 通过 require 引入依赖
  var $ = require('jquery');
  var Spinning = require('./spinning');

  // 通过 exports 对外提供接口
  exports.doSomething = ...

  // 或者通过 module.exports 提供整个接口
  module.exports = ...

});

由上面代码可以看出,我们模块用define来定义一个模块,然后里面生成一个function的接口,这个接口有三个形参分别是require, exports, module

require:用来引入依赖

exports:对外提供一个接口

module:将整个模块的接口暴露出去

此时我们将AMD和CMD做个对比

// AMD规范
define(['./a', './b'], function(a, b) {  // 依赖必须一开始就写好  
   a.doSomething()    
   // 此处略去 100 行    
   b.doSomething()    
   ...
});
// CMD规范
define(function(require, exports, module) {
   var a = require('./a')   
   a.doSomething()   
   // 此处略去 100 行   
   var b = require('./b') 
   // 依赖可以就近书写   
   b.doSomething()
   // ... 
});

不难看出其实两个很像,基本就是一个?生的,整个代码中也就获取依赖的时候不一样,AMD一开始就必须先将依赖获取了才能进行下一步的操作,而CMD则是当我们需要的时候才获取依赖,这样就相当于在AMD的优点上,又去掉了人家的缺点。

亲亲这边建议学CMD就够了哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值