实例讲解避免javascript冲突的方法


Posted in Javascript onJanuary 03, 2016

本文实例讲解了如何避免javascript中冲突的方法,需要的朋友可以了解一下

[1]工程师甲编写功能A

var a = 1;
var b = 2;
alert(a+b);//3

[2]工程师乙添加新功能B

var a = 2;
var b = 1;
alert(a-b);//1

[3]上一步中,工程师乙在不知情的情况下,定义了同名变量a,产生冲突。于是使用匿名函数将脚本包起来,让变量作用域控制在匿名函数之内。

//功能A
(function(){
var a = 1;

var b = 2;

alert(a+b);//3
})();
//功能B
(function(){

var a = 2;

var b = 1;

alert(a-b);//1
})();

[4]此时有了新需求,网页中加入功能C,且需要用到功能A中的变量b。于是在window作用域下定义一个全局变量,把它作为一个桥梁,完成各匿名函数之间的通信

//全局变量
var str;
//功能A
(function(){
var a = 1;

//将b的值赋给str

var b = str = 2;

alert(a+b);//3
})();
//功能B
(function(){

var a = 2;

var b = 1;

alert(a-b);//1
})();
//功能C
(function(){

//将str的值赋给b

var b = str;

alert(b);//2
})();

[5]但如果功能C还需要功能A中的变量a呢,这时就需要再定义一个全局变量

//全局变量
var str,str1;
//功能A
(function(){
//将a的值赋给str1

var a = str1 = 1;

//将b的值赋给str

var b = str = 2;

alert(a+b);//3
})();
//功能B
(function(){

var a = 2;

var b = 1;

alert(a-b);//1
})();
//功能C
(function(){

//将str1的值赋给a

var a = str1;

//将str的值赋给b

var b = str;

alert(a*b);//2
})();

[6]但随着匿名函数之间需要通信的变量越多,需要的全局变量也就越多。因此需要严格控制全局变量的数量,使用hash对象作为全局变量,可以将需要的变量都作为对象的属性,可以保证全局变量的个数足够少,同时拓展性非常好

//全局变量
var GLOBAL = {};
//功能A
(function(){
//将a的值赋给GLOBAL.str1

var a = GLOBAL.str1 = 1;

//将b的值赋给GLOBAL.str

var b = GLOBAL.str = 2;

alert(a+b);//3
})();
//功能B
(function(){

var a = 2;

var b = 1;

alert(a-b);//1
})();
//功能C
(function(){

//将GLOBAL.str1的值赋给a

var a = GLOBAL.str1;

//将GLOBAL.str的值赋给b

var b = GLOBAL.str;

alert(a*b);//2
})();

[7]但如果新增功能D,功能D需要和功能B通信,并使用功能B脚本中的变量a,开发功能D的是工程师丁

//全局变量
var GLOBAL = {};
//功能A
(function(){
//将a的值赋给GLOBAL.str1

var a = GLOBAL.str1 = 1;

//将b的值赋给GLOBAL.str

var b = GLOBAL.str = 2;

alert(a+b);//3
})();
//功能B
(function(){

//将a的值赋给GLOBAL.str1

var a = GLOBAL.str1 = 2;

var b = 1;

alert(a-b);//1
})();
//功能C
(function(){

//将GLOBAL.str1的值赋给a

var a = GLOBAL.str1;

//将GLOBAL.str的值赋给b

var b = GLOBAL.str;

alert(a*b);//2
})();
//功能D
(function(){

//将GLOBAL.str1的值赋给a

var a = GLOBAL.str1;

alert(a*2);//4
})();

[8]由于工程师丁只关心自己的匿名函数和功能B的匿名函数,使用GLOBAL.str却无意中覆盖了功能A中设置的同名变量,导致功能C出错。于是使用命名空间来解决这个问题,在不同的匿名函数下,根据功能声明一个不同的命名空间,然后每个匿名函数中的GLOBAL对象的属性都不要直接挂在GLOBAL对象上,而是挂在此匿名函数的命名空间下

//全局变量
var GLOBAL = {};
//功能A
(function(){
GLOBAL.A = {};

//将a的值赋给GLOBAL.A.str1

var a = GLOBAL.A.str1 = 1;

//将b的值赋给GLOBAL.A.str

var b = GLOBAL.A.str = 2;

alert(a+b);//3
})();
//功能B
(function(){

GLOBAL.B = {};

//将a的值赋给GLOBAL.B.str1

var a = GLOBAL.B.str1 = 2;

var b = 1;

alert(a-b);//1
})();
//功能C
(function(){

//将GLOBAL.A.str1的值赋给a

var a = GLOBAL.A.str1;

//将GLOBAL.A.str的值赋给b

var b = GLOBAL.A.str;

alert(a*b);//2
})();
//功能D
(function(){

//将GLOBAL.B.str1的值赋给a

var a = GLOBAL.B.str1;

alert(a*2);//4
})();

[9]如果同一个匿名函数中的程序非常复杂,变量名很多,命名空间还可以进一步拓展,生成二级命名空间

//以功能A为例
(function(){
var a = 1, b = 2;

GLOBAL.A = {};

GLOBAL.A.CAT = {};

GLOBAL.A.DOG = {};

GLOBAL.A.CAT.name = 'mimi';

GLOBAL.A.DOG.name = 'xiaobai';

GLOBAL.A.CAT.move = function(){};

GLOBAL.A.str1 = a;

GLOBAL.B.str = b;  
})();

[10]因为生成命名空间是个非常常用的功能,进一步将生成命名空间的功能定义成一个函数,方便调用,完整版本改写后的代码如下

var GLOBAL = {};
GLOBAL.namespace = function(str){
var arr = str.split('.');

var o = GLOBAL;

var start = 0;

if(arr[0] == 'GLOBAL'){


start = 1;

}else{


start = 0;

}

for(var i = start; i < arr.length; i++){


o[arr[i]] = o[arr[i]] || {};


o = o[arr[i]];

}
};
//功能A
(function(){

var a = 1;

var b = 2;

GLOBAL.namespace('A.CAT');

GLOBAL.namespace('A.DOG');

GLOBAL.A.CAT.name = 'mimi';

GLOBAL.A.DOG.name = 'xiaobai';

GLOBAL.A.CAT.move = function(){};

GLOBAL.A.str1 = a;

GLOBAL.A.str = b;  

alert(a+b);//3
})();
//功能B
(function(){

var a = 2;

var b = 1;

GLOBAL.namespace('B');

GLOBAL.B.str1 = a;

alert(a-b);//1
})();
//功能C
(function(){

var a = GLOBAL.A.str1;

var b = GLOBAL.A.str;

alert(a*b);//2
})();
//功能D
(function(){

var a = GLOBAL.B.str1;

alert(a*2);//4
})();

[11]代码的冲突问题已经解决了,但可维护性并不强。比如,现在需要让工程师甲去修改功能B。因为工程师甲写的脚本是关于功能A的,他并不知道功能B的脚本情况。为了改善这种局面,需要给代码添加适当的注释。

var GLOBAL = {};
GLOBAL.namespace = function(str){
var arr = str.split('.');

var o = GLOBAL;

var start = 0;

if(arr[0] == 'GLOBAL'){


start = 1;

}else{


start = 0;

}

for(var i = start; i < arr.length; i++){


o[arr[i]] = o[arr[i]] || {};


o = o[arr[i]];

}
};
/*
* @method 功能A:实现加法运算
* @author 工程师甲
* @connect 1234567
* @time 2015-01-01
*/

(function(){

var a = 1;

var b = 2;

GLOBAL.namespace('A.CAT');

GLOBAL.namespace('A.DOG');

GLOBAL.A.CAT.name = 'mimi';

GLOBAL.A.DOG.name = 'xiaobai';

GLOBAL.A.CAT.move = function(){};

GLOBAL.A.str1 = a;

GLOBAL.A.str = b;  

alert(a+b);//3
})();
/*
* @method 功能B:实现减法运算
* @author 工程师乙
* @connect 1234567
* @time 2015-01-01
*/
(function(){

var a = 2;

var b = 1;

GLOBAL.namespace('B');

GLOBAL.B.str1 = a;

alert(a-b);//1
})();
/*
* @method 功能C:实现乘法运算
* @author 工程师丙
* @connect 1234567
* @time 2015-01-01
*/
(function(){

var a = GLOBAL.A.str1;

var b = GLOBAL.A.str;

alert(a*b);//2
})();
/*
* @method 功能D:实现乘2运算
* @author 工程师丁
* @connect 1234567
* @time 2015-01-01
*/
(function(){

var a = GLOBAL.B.str1;

alert(a*2);//4
})();

让javascript不再冲突,需要

  •   [1]避免全局变量的泛滥
  • [2]合理使用命名空间

  • [3]为代码添加必要的注释

以上就是本文的详细内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
jQuery对象与DOM对象之间的转换方法
Apr 15 Javascript
仅IE不支持setTimeout/setInterval函数的第三个以上参数
May 25 Javascript
JS实现简易图片轮播效果的方法
Mar 25 Javascript
jquery实现页面常用的返回顶部效果
Mar 04 Javascript
AngularJs表单验证实例详解
May 30 Javascript
在javascript中使用com组件的简单实现方法
Aug 17 Javascript
BackBone及其实例探究_动力节点Java学院整理
Jul 14 Javascript
axios发送post请求springMVC接收不到参数的解决方法
Mar 05 Javascript
javascript实现对话框功能警告(alert 消息对话框)确认(confirm 消息对话框)
May 07 Javascript
layUI实现列表查询功能
Jul 27 Javascript
微信小程序框架的页面布局代码
Aug 17 Javascript
bootstrapValidator表单校验、更改状态、新增、移除校验字段的实例代码
May 19 Javascript
详解js中class的多种函数封装方法
Jan 03 #Javascript
js中利用tagname和id获取元素的方法
Jan 03 #Javascript
信息页文内画中画广告js实现代码(文中加载广告方式)
Jan 03 #Javascript
基于javascript实现简单计算器功能
Jan 03 #Javascript
详解Javascript事件驱动编程
Jan 03 #Javascript
基于javascript实现仿百度输入框自动匹配功能
Jan 03 #Javascript
js实现搜索框关键字智能匹配代码
Mar 26 #Javascript
You might like
php excel类 phpExcel使用方法介绍
2010/08/21 PHP
ajax在joomla中的原生态应用代码
2012/07/19 PHP
用PHP生成excel文件到指定目录
2015/06/22 PHP
php实现Session存储到Redis
2015/11/11 PHP
javascript的对话框详解与参数
2007/03/08 Javascript
IE浏览器打印的页眉页脚设置解决方法
2009/12/08 Javascript
当某个文本框成为焦点时即清除文本框内容
2014/04/28 Javascript
JS返回iframe中frameBorder属性值的方法
2015/04/01 Javascript
javascript用正则表达式过滤空格的实现代码
2016/06/14 Javascript
详解Angular2 关于*ngFor 嵌套循环
2017/05/22 Javascript
使用JS判断移动端手机横竖屏状态
2018/07/30 Javascript
JavaScript 继承 封装 多态实现及原理详解
2019/07/29 Javascript
vue实现pdf文档在线预览功能
2019/11/26 Javascript
vue+vuex+axios从后台获取数据存入vuex,组件之间共享数据操作
2020/07/31 Javascript
[03:56]显微镜下的DOTA2第十一期——鬼畜的死亡先知播音员
2014/06/23 DOTA
python处理二进制数据的方法
2015/06/03 Python
python数据结构链表之单向链表(实例讲解)
2017/07/25 Python
PyQt5利用QPainter绘制各种图形的实例
2017/10/19 Python
Python使用Pandas对csv文件进行数据处理的方法
2019/08/01 Python
Python通过kerberos安全认证操作kafka方式
2020/06/06 Python
记录模型训练时loss值的变化情况
2020/06/16 Python
结合CSS3的布局新特征谈谈常见布局方法
2016/01/22 HTML / CSS
CSS3 filter(滤镜)实现网页灰色或者黑色模式的代码
2020/11/30 HTML / CSS
家庭户外服装:Hawkshead
2017/11/02 全球购物
Stella McCartney官网:成衣、包袋、香水、内衣、童装及Adidas系列
2018/12/20 全球购物
ABOUT YOU匈牙利:500个最受欢迎的时尚品牌
2019/07/19 全球购物
暑假实习求职信范文
2013/09/22 职场文书
计算机通信专业推荐信
2014/02/22 职场文书
人力资源部经理助理岗位职责
2014/03/04 职场文书
学习教师法的心得体会
2014/09/03 职场文书
论文答辩开场白大全
2015/05/27 职场文书
2016春季运动会前导词
2015/11/25 职场文书
《失物招领》教学反思
2016/02/20 职场文书
教你怎么用PyCharm为同一服务器配置多个python解释器
2021/05/31 Python
MySQL 服务和数据库管理
2021/11/11 MySQL
MyBatis XPathParser解析器使用范例详解
2022/07/15 Java/Android