本文实例讲解了如何避免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的值赋给strvar b = str = 2;alert(a+b);//3})();//功能b(function(){var a = 2;var b = 1;alert(a-b);//1})();//功能c(function(){//将str的值赋给bvar b = str;alert(b);//2})();
[5]但如果功能c还需要功能a中的变量a呢,这时就需要再定义一个全局变量
//全局变量var str,str1;//功能a(function(){//将a的值赋给str1var a = str1 = 1;//将b的值赋给strvar b = str = 2;alert(a+b);//3})();//功能b(function(){var a = 2;var b = 1;alert(a-b);//1})();//功能c(function(){//将str1的值赋给avar a = str1;//将str的值赋给bvar b = str;alert(a*b);//2})();
[6]但随着匿名函数之间需要通信的变量越多,需要的全局变量也就越多。因此需要严格控制全局变量的数量,使用hash对象作为全局变量,可以将需要的变量都作为对象的属性,可以保证全局变量的个数足够少,同时拓展性非常好
//全局变量var global = {};//功能a(function(){//将a的值赋给global.str1var a = global.str1 = 1;//将b的值赋给global.strvar b = global.str = 2;alert(a+b);//3})();//功能b(function(){var a = 2;var b = 1;alert(a-b);//1})();//功能c(function(){//将global.str1的值赋给avar a = global.str1;//将global.str的值赋给bvar b = global.str;alert(a*b);//2})();
[7]但如果新增功能d,功能d需要和功能b通信,并使用功能b脚本中的变量a,开发功能d的是工程师丁
//全局变量var global = {};//功能a(function(){//将a的值赋给global.str1var a = global.str1 = 1;//将b的值赋给global.strvar b = global.str = 2;alert(a+b);//3})();//功能b(function(){//将a的值赋给global.str1var a = global.str1 = 2;var b = 1;alert(a-b);//1})();//功能c(function(){//将global.str1的值赋给avar a = global.str1;//将global.str的值赋给bvar b = global.str;alert(a*b);//2})();//功能d(function(){//将global.str1的值赋给avar a = global.str1;alert(a*2);//4})();
[8]由于工程师丁只关心自己的匿名函数和功能b的匿名函数,使用global.str却无意中覆盖了功能a中设置的同名变量,导致功能c出错。于是使用命名空间来解决这个问题,在不同的匿名函数下,根据功能声明一个不同的命名空间,然后每个匿名函数中的global对象的属性都不要直接挂在global对象上,而是挂在此匿名函数的命名空间下
//全局变量var global = {};//功能a(function(){global.a = {};//将a的值赋给global.a.str1var a = global.a.str1 = 1;//将b的值赋给global.a.strvar b = global.a.str = 2;alert(a+b);//3})();//功能b(function(){global.b = {};//将a的值赋给global.b.str1var a = global.b.str1 = 2;var b = 1;alert(a-b);//1})();//功能c(function(){//将global.a.str1的值赋给avar a = global.a.str1;//将global.a.str的值赋给bvar b = global.a.str;alert(a*b);//2})();//功能d(function(){//将global.b.str1的值赋给avar 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]为代码添加必要的注释
以上就是本文的详细内容,希望对大家的学习有所帮助。
【相关教程推荐】
1. javascript视频教程
2. javascript在线手册
3. bootstrap教程
