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

本文实例讲解了如何避免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]为代码添加必要的注释

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

(0)

相关推荐

  • jQuery库与其他JS库冲突的解决办法

    复制代码 代码如下: <script src="prototype.js"></script> <script src="jquery.js"></script> <script> jQuery.noConflict(); // Use jQuery via jQuery(-) jQuery(document).ready(function(){ jQuery("div").hide()

  • js函数名与form表单元素同名冲突的问题

    今天在导出Excel的时候用了Form 表单的input hidden 来区分导出和搜索.开始的时候js中的onClick事件的函数名 和 hidden 中的 id 命名一样.结果导致报错:调用函数的那一行对象不支持此属性. 找了很长时间都找不出原因,开始的时候一直以为是写错了某个字母,才发现js函数根本没有执行.后来没有办法直接调用了别的函数,发现就有用了,认为是函数名的原因,改了函数名才有用了.然后再将input中的id改成很函数名一样,又出现报错了.在没有下例验证之前,还一直以为是Thin

  • js不完美解决click和dblclick事件冲突问题

    情况描述 当某个元素,如:div,同时绑定了click事件和dblclick事件,而这两个事件又要处理相对独立的业务,也就是click的时候不能触发dblclick,dblclick的时候不能触发click.在实际测试中发现,当dblclick的时候,总会出现1次click.下文将要解决的就是这个问题. 情况分析 首先我们要清楚click和dblclick的执行顺序,测试过程略,下面是测试结果: click:mousedown -- mouseup -- click dblclick:mouse

  • jQuery避免$符和其他JS库冲突的方法对比

    jQuery中需要用到$符号,如果其他js库(例如大名鼎鼎的prototype)也定义了$符号,那么就会造成冲突,会影响到js代码的正常执行.jqeury提供了一些方案来避免这个问题,让我们来看看这几个方案有什么区别 方案1: 引入noConflict(),将$替换为其他符号 复制代码 代码如下: var $j = jQuery.noConflict(); $j(document).ready(function(){ $j("#btn1").click(function(){ aler

  • jquery与js函数冲突的两种解决方法

    如果您还有别的要求,想继续使用原先的$(),同时还需要与别的类库不冲突的话,还有两种解决方法 其一: 复制代码 代码如下: jQuery.noConflict(); jQuery(function($) { $("p").click(function() //在函数内继续可以使用jquery类库的$()方法 { alert($(this).text()); }) }) var JsCOM_cr = $("cr"); // 在函数外面,照样可以使用JsCOM.js的$

  • JS 学习笔记 防止发生命名冲突

    为了防止发生命名冲突,可以建立自己的代码库. 就想 Js代码 复制代码 代码如下: ziggy_js=function(){} ziggy_js.ui=function(){} ziggy_js.ui.alerts=function(){} ziggy_js.ui.alerts.showErrorAlert=function(){ alert("An error occurred"); } ziggy_js.ui.alerts.showErrorAlert(); //以在其中定义类 z

  • js中单引号与双引号冲突问题解决方法

    如何解决js中单引与双引冲突,想下面的这段代码: 复制代码 代码如下: html += ' <a onclick="return removeOpenCss('+e.point.lng+e.point.lat+')">取消</a>'; 这是js中的代码,如果这里这样写的话,会提示js错误,是因为removeOpenCss方法里的参数没有单引或者双引,如果这里,这样写的话: 复制代码 代码如下: html += ' <a onclick="retu

  • JQuery的$和其它JS发生冲突的快速解决方法

    众所周知,jQuery是目前最流行的JS封装包,简化了很多复杂的JS程序,JQuery讲浏览器DOM树定义为$,通过$来获取各个子节点. 然后,JS插件并非只有JQuery,还有prototype.js 等其它比较好的插件.它们也使用$.所以有时候同时使用这个两个JS插件的时候,就会出现$的使用权冲突问题.现在我们来看看如何解决这个冲突问题.请看下文: 我们都知道JQuery有一个函数,jquery.noConflict() 它的作用是讲$的控制权转让出去.然后我们可以通过jQuery代替$来获

  • 解决css和js的{}与smarty定界符冲突问题的两种方法

    当输入url地址后网页出现:Fatal error: Uncaught exception 'SmartyCompilerException' with message 'Syntax Error in template "E:\wamp\www\cms\system/templates/index.html" on line 79 "$("#job").load("./system/templates/touch/test.php",

  • 导入extjs、jquery 文件时$使用冲突问题解决方法

    1.在最近做项目时,在html页面中,没有导入jquery文件时,可以正常保存,而导入jquery文件后,则不能不存了 经过调试后,发现导入的jquery文件和现有的extjs文件冲突了(原因是$符号的冲突) jQuery与ExtJS之间发生冲突,但是在非IE内核下是可以的,是由于$符号的冲突,解决办法就是把jQuery的$符号用其他来代替,代码如下: 复制代码 代码如下: <script type="text/javascript" src="js/jquery.js

随机推荐