大家都知道,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. 深入浅出Windows Phone 8应用开发

    刚刚拿到<深入浅出Windows Phone 8应用开发>这本书,开始捣鼓我的Nokia Lumia 925T,已经有开发一个属于自己的App的想法了,计划先不公布了,等我这个App上线了 ...

  2. [ios]离屏渲染优化

    原文链接:https://mp.weixin.qq.com/s?__biz=MjM5NTIyNTUyMQ==&mid=2709544818&idx=1&sn=62d0d2e9a ...

  3. 理解css中的position-static\relative\fixed\absolute

    position属性有四个值: static(静态定位):是默认值,不会被特殊的定位,遵循正常的文档流对象,对象占用文档空间,该方式下,top.right.bottom.left.z-index等属性 ...

  4. 最全面的Java多线程用法解析

    1.创建线程 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口.在使用Runnable接口时需要建立一个Thread实例.因此,无论是通过Thread类还是Runnable ...

  5. SlickGrid example 2: 按想要的风格展示列

    先上效果图. 代码: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http:// ...

  6. Javascript中最常用的经典技巧

    1. oncontextmenu="window.event.returnValue=false" 将彻底屏蔽鼠标右键<table border oncontextmenu= ...

  7. 网络编程中获取域名和id的方法

    package com.lanqiao.java.test; import java.net.InetAddress;import java.net.UnknownHostException; pub ...

  8. Pipe(点积叉积的应用POJ1039)

    Pipe Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9723   Accepted: 2964 Description ...

  9. 第十二届浙江省大学生程序设计大赛-Beauty of Array 分类: 比赛 2015-06-26 14:27 12人阅读 评论(0) 收藏

    Beauty of Array Time Limit: 2 Seconds Memory Limit: 65536 KB Edward has an array A with N integers. ...

  10. JAVA基础知识之IO-File类

    File类介绍 File是java.io包下面的一个类,代表与平台无关的文件或者目录.JAVA中,无论文件还是目录,都可以看作File类的一个对象.File类能对文件或目录新建,删除,获取属性等操作, ...