大家都知道,js中的变量(variable)有其作用范围,比如:函数里用var定义的变量在函数外是看不到的,而定义在函数外面的变量(不能有没有var修饰)均是全局变量,在js程序的任何位置都可以访问。嗯,实际上我们在工作过程中,业务逻辑比较多,而一个业务逻辑包含多个函数,函数之间共享使用某个变量,这样问题就来了,如果另外一个业务逻辑不小心定义了或者修改了这个变量,就会造成这个全局变量被污染,前一个业务逻辑就会出现脏读,过程测试如下:

一个很长的页面脚本程序包含两个子业务处理过程1和2,业务处理程序1需要定义两个函数和一个变量,一个函数设置变量,一个函数读取输出变量,如下:

 
 1 /*****页面业务逻辑1***begin*****/
2
3 //定义一个全局变量,供逻辑1中的各函数共享使用
4 var test = 0;
5 function setFlag() {
6 test = 1;
7 }
8 function displayFlag() {
9 console.log(test);
10 }
11
12 /*****页面业务逻辑1***end*****/
 

其他业务处理程序脚本:

1 /*
2 * ……………………………………
3 * 中间业务逻辑,篇幅很长
4 * ……………………………………
5 */

业务处理程序2开始,逻辑处理也定义了两个函数和一个变量,一个函数设置变量,一个函数读取变量进行其他处理,不幸的是,这个全局变量采用了同业务逻辑1相同的名字:

 
 1 /*****页面业务逻辑2***begin*****/
2
3 //定义一个全局变量,供逻辑1中的各函数共享使用
4 var test = 0;
5 function setVarable() {
6 test = 1;
7 }
8 function displayV() {
9 console.log(test);
10 }
11
12 /*****页面业务逻辑2***end*****/
 

程序过程在进行逻辑2后再进行逻辑1,此时出现了意外:

1 setVarable();   //逻辑2不小心修改了该值
2
3 displayFlag(); //error:预期输出1,但是却脏读成了2

输出结果如下:

很明显,实际输出的结果并不是期望的结果,此外还有另外一种情况,如果某个js脚本程序被共享为一个共用的脚本块,在多个地方调用(引入)这个脚本块时,也会很容易出现这个问题。

而模块化编程(Module)的出现就解决了这个问题,除此之外模块化编程还有其他几个特点:

1. 维护一个干净前端脚本的变量环境,保护一定作用范围内定义的全局变量不被范围外程序的污染;

2. 前端脚本程序的可重用性大大提高,可读性和可维护性进一步增强;

3. 可以组合多个module脚本,抽象成一个公共的脚本库,提高代码的开发效率;

前面说过,函数内部定义的变量函数外看不到(即不可用),为了保护变量环境的作用域,这正是我们需要的结果,故把整个业务处理逻辑扔到一个函数里实现就可以实现一个模块的定义,改写上面逻辑1和逻辑2的代码如下:

 
 1 /*****页面业务逻辑1********/
2 function HandleOne() {
3 var test = 0;
4 this.setFlag = function() {
5 test = 1;
6 }
7 this.displayFlag = function() {
8 console.log("这是逻辑1中的变量值:" + test);
9 }
10 //返回this对象,以访问module里定义的函数
11 return this;
12 }
13
14 /*
15 * ……………………………………
16 * 中间业务逻辑,篇幅很长
17 * ……………………………………
18 */
19
20 /*****页面业务逻辑2********/
21 function HandleTwo() {
22 var test;
23 this.setVarable = function() {
24 test = 2;
25 }
26 this.displayV = function() {
27 console.log("这是逻辑2中的变量值:" + test);
28 }
29 //返回this对象,以访问module里定义的函数
30 return this;
31 }
32
33 var H1 = HandleOne();
34 var H2 = HandleTwo();
35
36 H2.setVarable(); //逻辑2修改了自己的变量
37
38 H1.displayFlag(); //逻辑1输出自己的变量
39
40 H2.displayV(); //逻辑2输出自己的变量
 

输出结果如下:

由上图可知,在模块化编程下,每个模块内部使用的共用变量都很好的被保护起来了,不在收到外面其他逻辑处理的干扰,但是上述过程需要我们定义两个函数模块,如果我们不想额外定义任何中间变量,我们可以采用匿名函数来重新实现上述过程,代码改写如下:

 
 1 /*****页面业务逻辑1********/
2 var H1 = (function() {
3 var test = 0;
4 this.setFlag = function() {
5 test = 1;
6 }
7 this.displayFlag = function() {
8 console.log("这是逻辑1中的变量值:" + test);
9 }
10 //返回this对象,以访问module里定义的函数
11 return this;
12 } ());
13
14 /*
15 * ……………………………………
16 * 中间业务逻辑,篇幅很长
17 * ……………………………………
18 */
19
20 /*****页面业务逻辑2********/
21 var H2 = (function() {
22 var test;
23 this.setVarable = function() {
24 test = 2;
25 }
26 this.displayV = function() {
27 console.log("这是逻辑2中的变量值:" + test);
28 }
29 //返回this对象,以访问module里定义的函数
30 return this;
31 } ());
32
33 H2.setVarable(); //逻辑2修改了自己的变量
34
35 H1.displayFlag(); //逻辑1输出自己的变量
36
37 H2.displayV(); //逻辑2输出自己的变量
 

上面的是用匿名函数实现的模块化封装,输出的结果同实体函数时一样,是不是比实体函数时更加简洁了?!

注:上述过程中我们在每个模块中返回了this对象,是因为我们需要在后续的逻辑中调用该模块中的函数,如果在实践过程中模块处理程序不需要被外部逻辑调用,而只是在模块内部输出结果即可的话,我们只需返回模块最终处理的结果值或者不需要返回语句,依据具体情况具体分析。

通过上述的例子我们可以总结出模块化的一般思路:

1. 把相关联的一系列函数及变量的定义放在一个函数(匿名函数也行)中即可形成一个模块,模块中的变量和函数的作用域仅限于模块内部,外部无法直接调用,模块可以返回既定逻辑的处理结果。

2. 如果需要在模块外部提供调用模块中函数或者变量的接口,则需要将模块中函数或变量的定义用this标记,然后在模块最后返回这个this对象(函数中的this对象指的是window对象)。

模块化的编程思路如下:

 
 1 //实体函数时的模块化思路
2 function Moudle() {
3
4 var theResult;
5
6 //do something here
7
8 //这一句可有可无,有则返回最终的处理结果
9 return theResult;
10 }
11 //执行模块过程,有返回值时可以接收返回值
12 Moudle();
13
14 //匿名函数时的模块化思路
15 var result = (function() {
16 var theResult;
17
18 //do something here
19
20 //这一句可有可无,有则返回最终的处理结果
21 return theResult;
22 });

文章来自http://www.360doc.com/content/15/0810/21/27084883_490826869.shtml

js模块化编程总结的更多相关文章

  1. 从273二手车的M站点初探js模块化编程

    前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数 ...

  2. require.js实现js模块化编程(一)

    1.认识require.js: 官方文档:http://requirejs.org/RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一.最新版本的Requ ...

  3. require.js实现js模块化编程(二):RequireJS Optimizer

    require.js实现js模块化编程(二):RequireJS Optimizer 这一节,我们主要学习一下require.js所提供的一个优化工具r.js的用法. 1.认识RequireJS Op ...

  4. 初步理解require.js模块化编程

    初步理解require.js模块化编程 一.Javascript模块化编程 目前,通行的Javascript模块规范共有两种:CommonJS和AMD. 1.commonjs 2009年,美国程序员R ...

  5. [转]js模块化编程之彻底弄懂CommonJS和AMD/CMD!

    原文: https://www.cnblogs.com/chenguangliang/p/5856701.html ------------------------------------------ ...

  6. js模块化编程之彻底弄懂CommonJS和AMD/CMD!

    先回答我:为什么模块很重要? 答:因为有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块.但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则你有你的写法,我有我的写 ...

  7. 好文推荐系列-------(5)js模块化编程

    本文主要来源于阮一峰的<Javascript模块化编程>系列文章整合,原文地址:http://www.ruanyifeng.com/blog/2012/10/javascript_modu ...

  8. JS模块化编程(一):CommonJS,AMD/CMD

    前言 模块化是什么? 为什么采用模块化? 场景: 一个html,因不同的业务需求开发,会不断的引入js文件.另外,a.js和b.js中的变量或函数必须是全局的,才能暴露给使用方. <script ...

  9. JS模块化编程(二)

    背景 我们常在页面引用js遇到下面情况 <script src="1.js"></script> <script src="2.js&quo ...

随机推荐

  1. PHP多表取数据的代码优化

    <?php header("Content-type: text/html; charset=utf-8"); //假设这里的$goods_arr  和 $shop_arr  ...

  2. [ios][swift]swift GPS传感器的调用

    在Info.plist文件中添加如下配置:(1)NSLocationAlwaysUsageDescription(2)NSLocationWhenInUseUsageDescription swift ...

  3. C语言的数组名和对数组名取地址

    http://blog.csdn.net/zdcsky123/article/details/6517811 相信不少的C语言初学者都知道,数组名相当于指针,指向数组的首地址,而函数名相当于函数指针, ...

  4. 周赛-DZY Loves Chessboard 分类: 比赛 搜索 2015-08-08 15:48 4人阅读 评论(0) 收藏

    DZY Loves Chessboard time limit per test 1 second memory limit per test 256 megabytes input standard ...

  5. mongoDB Replica集群配置(1主+1从+1仲裁)

    1.mongoDB节点介绍 主节点(Primary) 在复制集中,主节点是唯一能够接收写请求的节点.MongoDB在主节点进行写操作,并将这些操作记录到主节点的oplog中.而从节点将会从oplog复 ...

  6. DedeCMS生成首页html静态文件的教程

    http://www.mubanzhijia.com/jishujiaocheng/826.html 在dedecms后台点击"更新主页Html"时,发生了什么?dedecms生成 ...

  7. shell脚本之if语句

    一.前言 结构化编程中,主要有三种结构:顺序.分支.循环.由此可见分支判断的重要性. 而且在shell编程中往往会遇到进行判断的情况,比如:判断文件是否存在.目录是否存在等等. 二.if语句的结构 i ...

  8. 微软DbHelper

    using System; using System.Configuration; using System.Data; using System.Data.Common; using System. ...

  9. ContentProvider官方教程(10)<provider>元素及属性介绍

    The <provider> Element Like Activity and Service components, a subclass of ContentProvider mus ...

  10. BZOJ 1488: [HNOI2009]图的同构 polay

    题意:两个图AB同构:把A的顶点重新编号后与B一模一样.求n个顶点的图一共有多少个?(同构的算一种) 思路:边有n*(n-1)/2,这些边可以有可以没有,所以等同于边的颜色有两种.然后将n划分成循环节 ...