js模块化编程总结

  大家都知道,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

时间: 2024-10-17 17:37:14

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

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

前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数据. 273这个M站点是产品推荐我看的.第一眼看这个产品时我就再想他们这个三次加载和翻页按钮的方式,那么小分页的pageIndex是怎么计算的.所以就顺便看了下源码. 提到看源码时用到了Chrome浏览器的格式化工具(还是朋友推荐我的,不过这个格式化按钮的确不明显,不会的话自行百度). 三次加载和分

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

初步理解require.js模块化编程 一.Javascript模块化编程 目前,通行的Javascript模块规范共有两种:CommonJS和AMD. 1.commonjs 2009年,美国程序员Ryan Dahl创造了node.js项目,将javascript语言用于服务器端编程,这标志”Javascript模块化编程”正式诞生. 在浏览器环境下,没有模块也不是特别大的问题,毕竟网页程序的复杂性有限:但是在服务器端,一定要有模块,与操作系统和其他应用程序互动,否则根本没法编程. node.j

JS模块化编程

js模块化编程演化 博客文章: 1 传统模块化:http://www.ruanyifeng.com/blog/2012/10/javascript_module.html 2 AMD规范:http://www.ruanyifeng.com/blog/2012/10/asynchronous_module_definition.html 3 RequireJs:http://www.ruanyifeng.com/blog/2012/11/require_js.html 现在有两大模块化规范,使用在

JS模块化编程(二)

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

js模块化编程(二):AMD规范

转自 ruanyifeng 系列目录: Javascript模块化编程(一):模块的写法 Javascript模块化编程(二):AMD规范 Javascript模块化编程(三):Require.js的用法 今天介绍如何规范地使用模块. 接上文 七.模块的规范 先想一想,为什么模块很重要?因为有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块.但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则你有你的写法,我有我的写法,岂不是乱了套!考虑到Javascript模

js模块化编程(三):Require.js的用法

转自 ruanyifeng 系列目录: Javascript模块化编程(一):模块的写法 Javascript模块化编程(二):AMD规范 Javascript模块化编程(三):Require.js的用法 介绍了Javascript模块原型和理论概念,今天介绍如何将它们用于实战.我采用的是一个非常流行的库require.js. 一.为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码越来越多,一个文件不够了,必须分成多

js模块化编程(一):模块的写法

转自 ruanyifeng 系列目录: Javascript模块化编程(一):模块的写法 Javascript模块化编程(二):AMD规范 Javascript模块化编程(三):Require.js的用法 随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂.网页越来越像桌面程序,需要一个团队分工协作.进度管理.单元测试等等......开发者不得不使用软件工程的方法,管理网页的业务逻辑.Javascript模块化编程,已经成为一个迫切的需求.理想

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

先回答我:为什么模块很重要? 答:因为有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块.但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则你有你的写法,我有我的写法,岂不是乱了套! 于是下面三个模块规范出来了,这篇文章也出来了(拼出来的 {捂脸笑}). JS中的模块规范(CommonJS,AMD,CMD),如果你听过js模块化这个东西,那么你就应该听过或CommonJS或AMD甚至是CMD这些规范咯,我也听过,但之前也真的是听听而已. 现在就看看吧,这些规范

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

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