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
js模块化编程总结的更多相关文章
- 从273二手车的M站点初探js模块化编程
前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数 ...
- require.js实现js模块化编程(一)
1.认识require.js: 官方文档:http://requirejs.org/RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一.最新版本的Requ ...
- require.js实现js模块化编程(二):RequireJS Optimizer
require.js实现js模块化编程(二):RequireJS Optimizer 这一节,我们主要学习一下require.js所提供的一个优化工具r.js的用法. 1.认识RequireJS Op ...
- 初步理解require.js模块化编程
初步理解require.js模块化编程 一.Javascript模块化编程 目前,通行的Javascript模块规范共有两种:CommonJS和AMD. 1.commonjs 2009年,美国程序员R ...
- [转]js模块化编程之彻底弄懂CommonJS和AMD/CMD!
原文: https://www.cnblogs.com/chenguangliang/p/5856701.html ------------------------------------------ ...
- js模块化编程之彻底弄懂CommonJS和AMD/CMD!
先回答我:为什么模块很重要? 答:因为有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块.但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则你有你的写法,我有我的写 ...
- 好文推荐系列-------(5)js模块化编程
本文主要来源于阮一峰的<Javascript模块化编程>系列文章整合,原文地址:http://www.ruanyifeng.com/blog/2012/10/javascript_modu ...
- JS模块化编程(一):CommonJS,AMD/CMD
前言 模块化是什么? 为什么采用模块化? 场景: 一个html,因不同的业务需求开发,会不断的引入js文件.另外,a.js和b.js中的变量或函数必须是全局的,才能暴露给使用方. <script ...
- JS模块化编程(二)
背景 我们常在页面引用js遇到下面情况 <script src="1.js"></script> <script src="2.js&quo ...
随机推荐
- PHP正则表达式的使用
1. 正则表达式的主要作用是:分割.匹配.查找.替换2. 正则表达式中包括的元素:原子(普通字符:a-z A-Z 0-9 .原子表.转义字符),元字符(有特殊功能的字符),模式修正符(系统内置部分字符 ...
- linux下echo命令详解(转)
linux的echo命令, 在shell编程中极为常用, 在终端下打印变量value的时候也是常常用到的, 因此有必要了解下echo的用法 echo命令的功能是在显示器上显示一段文字,一般起到一个 ...
- sql必知必会(第四版) 学习笔记
还有一个<Sqlserver2008技术内幕>的笔记,也很好!~ http://www.cnblogs.com/liupeng61624/p/4354983.html 温习一遍简单的sql ...
- 百度地图瓦片原理 | 百度map使用教程
百度地图瓦片原理: http://blog.csdn.net/mygisforum/article/details/22997879 百度map使用教程: http://www.myexception ...
- jquery ui 常用(二)(对话框 | 旋转器 | 工具提示框(表单) | 特效(百叶窗) )
一.添加信息的对话框 http://www.w3cschool.cc/try/tryit.php?filename=jqueryui-example-dialog-modal-form. 模态表单 ...
- [转]android使用shape stroke描边只保留底部
在项目中遇到这种情况:由于一些原因,自己需要用LinearLayout的垂直布局做出ListView的那种效果,但是ListView是自带了分割线的,而且顶部底部都是没有分割线的,每个item中间都是 ...
- YTU 2297: KMP模式匹配 三(串)
2297: KMP模式匹配 三(串) 时间限制: 1 Sec 内存限制: 128 MB 提交: 25 解决: 16 [提交][状态][讨论版] [Edit] [TestData] 题目描述 输入一 ...
- jQuery.validator 详解
jQuery.validator 详解二 前言:上一篇详细的介绍了jQuery.validator( 版本v1.13.0 )的验证规则,这一篇重点讲述它的源码结构,及如何来对元素进行验证,错误消息提示 ...
- AndroidManifest.xml 详解
第1部分 标签库+包路径+版本控制 <manifest xmlns:android="http://schemas.android.com/apk/res/android" ...
- 周赛-Colored Sticks 分类: 比赛 2015-08-02 09:33 7人阅读 评论(0) 收藏
Colored Sticks Time Limit: 5000MS Memory Limit: 128000K Total Submissions: 32423 Accepted: 8556 Desc ...