模块化开发

模块化开发

JiangWen Lv4

前言

ES6之前,Javascript并没有模块体系。但在实际开发中,我们需要模块化编程的开发提高效率和维护性,于是产生了几类模块化的标准

模块的概念:模块就是实现特定功能的一组方法

原始写法


函数写法:

1
2
3
4
5
6
function m1(){
//...
}
function m2(){
//...
}

只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块。

  • 使用:直接调用方法就行了。
  • 缺点:”污染”了全局变量,无法保证不与其他模块发生变量名冲突,而且模块成员之间看不出直接关系。

对象写法:

1
2
3
4
5
6
7
8
9
var module = new Object({
_count : 0,
m1 : function (){
//...
},
m2 : function (){
//...
}
});

对象写法 为了解决上面的缺点,可以把模块写成一个对象,所有的模块成员都放到这个对象里面

  • 使用:调用这个对象的属性
  • 缺点:暴露所有模块成员,内部状态可以被外部改写
1
module._count = 1;

立即执行函数写法:

1
2
3
4
5
6
7
8
9
10
var module = (function(){
var _count = 0;
var m1 = function(){
alert(_count)
}
var m2 = function(){
alert(_count + 1)
}
return {m1,m2}
})()

使用”立即执行函数(IIFE)”,利用函数作用域中的外部函数无法访问内部函数规则,从而私有化内部属性,并函数结果以对象形式返回给module

  • 使用:调用返回对象中的方法属性

主流模块规范

​ ES6标准之前,JavaScript并没有模块体系,浏览器端通过<script>引入的代码被当作脚本执行。社区中则制定了一些标准:如CommonJS、AMD、CMD ,CommonJS同步加载主要用于服务端,AMD、CMD异步加载则用于浏览器端。

CommonJS规范

NodeJS是CommonJS规范的主要实践者,CommonJS用同步的方式加载模块。在Server上模块文件都在本地磁盘,所以读取非常快没什么不妥,但是在Browser由于网络的原因,更合理的方案是异步加载。

AMD规范

AMD(Asynchronous Module Definition)异步模块定义。AMD其实是RequireJS在推广的过程中对模块定义的范围化的产出,它是一个在浏览器端模块化开发的规范。 它不是javascript原生支持,所以使用AMD规范进行页面开发需要用到对应的库,也就是RequireJS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//定义模块define(id?, dependencies?, factory)
//- id:模块名
//- dependencies:当前模块依赖的模块
//- factory:工厂方法,一般直接返回一个对象
define('math',['jquery'], function ($) {//引入jQuery模块
return {
add: function(x,y){
return x + y;
}
};
});

//------------------------------------------------------------------------------------

//读取模块require([modlue], callback)
//别名配置
requirejs.config({
paths: {
jquery: 'jquery.min' //可以省略.js
}
});
//引入模块,用变量$表示jquery模块
requirejs(['jquery'], function ($) {
$('body').css('background-color','red');
});

CMD规范

CMD(Common Module Definition) 通用模块定义。 CMD是在sea.js推广的过程中产生的。在CMD规范中,一个模块就是一个文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 定义模块
define(function(require, exprots, module) {
const fs = require('fs'); //接受模块标识作为唯一参数
exports.module = { // exports,module则和CommonJS类似
props: 'value'
};
});

// ------------------------------------------------------------------------------------

// 加载模块
seajs.use(['test.js'], function(test_exports) {
// ....
});

CMD和AMD的异同

\AMDCMD
对依赖模块的执行时机处理不同推崇依赖前置,在定义的时候就要声明其依赖的模块推崇就近依赖,只有在用到这个module的时候才去require
加载方式async异步加载async异步加载
适用环境browserbrowser
执行module的方式加载module完成后就会执行该module加载完某个依赖后并不执行,只是下载而已。

★ES6模块(服务器&浏览器端通用方案)

\CommonJSES6
加载运行时加载编译时输出接口
导入次数
模块输出

引用参考:

  1. ES6标准入门——阮一峰
1
2
3
4
5
6
7
8
9
10
11
12
let module = (function () {
let _count = 0;
let m1 = function () {
console.log(_count);
}
let m2 = function () {
console.log(_count + 1)
}
return {
m1,m2
}
})()

使用上面的写法,外部代码无法读取内部的_count变量,module就是Javascript模块的基本写法。

  • 标题: 模块化开发
  • 作者: JiangWen
  • 创建于: 2020-02-28 12:15:00
  • 更新于: 2023-06-18 15:54:09
  • 链接: https://blog.jiangwen.site/2020/02/28/Javascript/模块化开发/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
 评论