一,我们的习惯
// 普通变量 var a = 1 * 2; // 对象变量 var obj1 = new Object(); var obj2 = {}; // 快捷方式 var obj3 = { property1 : "我是属性1", property2 : "我是属性2", function1 : function() { alert("obj3的函数"); }, function2 : function(param) { alert("有参函数"); } }; // 数组变量 var arr1 = new Array(); var arr2 = [ 1, 2, 3, 4, 5 ];// 快捷方式 var arr2 = [ 1, 2, [ 1, 2, 3, 4, 5 ], 4, 5 ];// 快捷方式 // map类型 var map = { title : "标题", logo : "/logos/welcome.png", age : 20, sex : "男" }; // 函数变量 var f = function() { alert("我是函数变量,给我一对括号吧"); }; // 匿名函数变量 // 这里的函数名fact 是为匿名函数起的一个名字,近供自身调用,一般用于递归 var f = function fact(x) { if (x <= 1) return 1; else return x * fact(x - 1); };
二,如何去改善代码
这里我们要用到匿名函数,当然其他函数也可以,
1,什么是匿名函数
匿名函数就是一个无名称的类函数的表达式!
- 无参匿名函数,与函数的区别是:没有函数名
function(){
alert("我是一个匿名函数,没有参数");
}
- 有参匿名函数,与函数的区别:没有函数名
var fn=function(param){
alert("我是一个匿名函数,有参数"+param);
}
- 有名字的匿名函数,与函数的区别:注意这个名字,仅自身可用,其他地方无法引用,并且必须有一个左值
var fn=function increase(num){
if(num>100){
return;
}else{
increase(++num);
}
}
2,原理:在函数内的变量,其作用域范围为当前函数内,函数执行完毕,变量失效。如果想设置全局变量,将其暴露出去即可
(function(window){ var _common={}; _common.faxbox={ modified:false, _emailList:false, emailList:function(){ if(this._emailList){ return this._emailList; } this._emailList= zk.Widget.$(jq("$emailList")); return this._emailList; }, eachFaxList:function(callback){ var itemInter =this.emailList().itemIterator() ; while(itemInter.hasNext()){ callback.apply(this,[itemInter.next()]); } }, switchReadStatus:function(listitem,status){ var statusLabel =listitem.firstChild.firstChild; var readImage =listitem.firstChild.nextSibling.firstChild.firstChild; var arr =statusLabel.getValue().split(":"); if(arr[1]!=status){ this.modified=true; }else{ listitem.setSelected(false); return; } arr[1]=status; statusLabel.setValue(arr.join(":")); switch(status){ case 0: readImage.setSrc("/icon/images/email_unread.png"); break; case 1: readImage.setSrc("/icon/images/marktrans.png"); break; case 2: readImage.setSrc("/icon/images/email_replied.png"); break; case 3: readImage.setSrc("/icon/images/email_forward.png"); break; case 4: readImage.setSrc("/icon/images/email_forwardReplied.png"); break; default: break; } }, switchColorStatus:function(listitem,status){ var statusLabel =listitem.firstChild.firstChild; var arr =statusLabel.getValue().split(":"); if(arr[3]!=status){ this.modified=true; }else{ listitem.setSelected(false); return; } arr[3]=status; statusLabel.setValue(arr.join(":")); var listcell =listitem.lastChild.previousSibling.previousSibling; var subjectCell = listcell.nextSibling; switch(status){ case 1://红色 jq(subjectCell).attr("style","color: #ff3747 !important;font-weight:;"); listcell.setImage("/icon/images/mark1.gif"); break; case 2://绿色 jq(subjectCell).attr("style","color: #29dd3d !important;font-weight:;"); listcell.setImage("/icon/images/mark2.gif"); break; case 3://橙色 jq(subjectCell).attr("style","color: #ffa127 !important;font-weight:;"); listcell.setImage("/icon/images/mark3.gif"); break; case 4://蓝色 jq(subjectCell).attr("style","color: #36d1ff !important;font-weight:;"); listcell.setImage("/icon/images/mark4.gif"); break; case 5://粉色 jq(subjectCell).attr("style","color:#ffb7d7 !important;font-weight:;"); listcell.setImage("/icon/images/mark5.gif"); break; case 6://青色 jq(subjectCell).attr("style","color: #85dfd2 !important;font-weight:;"); listcell.setImage("/icon/images/mark6.gif"); break; case 7://黄色 jq(subjectCell).attr("style","color: #e2c462 !important;font-weight:;"); listcell.setImage("/icon/images/mark7.gif"); break; case 8://紫色 jq(subjectCell).attr("style","color: #ed50f8 !important;font-weight:;"); listcell.setImage("/icon/images/mark8.gif"); break; case 9://灰色 jq(subjectCell).attr("style","color: #a1a3a4 !important;font-weight:;"); listcell.setImage("/icon/images/mark9.gif"); break; default: jq(subjectCell).attr("style","color:;font-weight:;"); listcell.setImage("/icon/images/marktrans.png"); break; } }, selectAll:function(){//选择所有邮件 this.emailList().selectAll(false,null); }, endMarkStatus:function(){ if(this.modified)return; //1停止处理框 zk.endProcessing(); //2,提示用户 jq.alert("您选择的邮件已经是当前状态,无需再次标记。",{title:"选择邮件出错"}); //3停止事件的传播,阻止调用后台代码 jq.stop(); }, checkSelect:function(){ if(this.emailList().getSelectedItems().length){ jq.alert("请选择邮件!",{title:"选择邮件出错"}); jq.stop(); } }, _select:function(status){ this.eachFaxList(function(listitem){ var rsLabel = listitem.firstChild.firstChild; if(rsLabel.getValue().split(":")[1]==status){ listitem.setSelected(true); }else{ listitem.setSelected(false); } }); }, selectUnRead:function(){ this._select("0"); }, selectRead:function(){ this._select("1"); }, selectReplied:function(){ this._select("2"); }, selectForwarded:function(){ this._select("3"); }, selectRF:function(){ this._select("4"); }, selectInvert:function(){ this.eachFaxList(function(listitem){ if(listitem.isSelected()){ listitem.setSelected(false); }else{ listitem.setSelected(true); } }); }, clearSelected:function(){ this.emailList().clearSelection(); }, markReaded:function(){ this.checkSelect(); zk.startProcessing(1); this.eachFaxList(function(listitem){ if(listitem.isSelected()){ this.switchReadStatus(listitem,1); } }); this.endMarkStatus(); }, markUnReaded:function(){ this.checkSelect(); zk.startProcessing(1); this.eachFaxList(function(listitem){ if(listitem.isSelected()){ this.switchReadStatus(listitem,0); } }); this.endMarkStatus(); }, markColor:function(status){ this.checkSelect(); zk.startProcessing(1); this.eachFaxList(function(listitem){ if(status==-1){ this.switchColorStatus(listitem,status); }else if(listitem.isSelected()){ this.switchColorStatus(listitem,status); } }); this.endMarkStatus(); }, markLevel:function(level){ if(!(level==-1||level==0||level==1))return; this.checkSelect(); zk.startProcessing(1); this.eachFaxList(function(listitem){ if(!listitem.isSelected()){ return; } var statusLabel =listitem.firstChild.firstChild; var arr =statusLabel.getValue().split(":"); if(arr[2]!=status){ this.modified=true; }else{ listitem.setSelected(false); return; } arr[2]=level; statusLabel.setValue(arr.join(":")); var levelImage =listitem.firstChild.nextSibling.firstChild.lastChild; switch(level){ case -1: levelImage.setSrc("/icon/images/level3_mini.png"); break; case 0: levelImage.setSrc("/icon/images/level2_mini.png"); break; case 1: levelImage.setSrc("/icon/images/level1_mini.png"); break; } }); this.endMarkStatus(); } }; jq(window).blur(function(){ _common.win.isFocus=false; }); jq(window).focus(function(){ _common.win.isFocus=true; }); _common.win={ isFocus:true }; //暴露common window.common=_common; })(window);
三,为什么要这么做?
1, 首先我们来比较一下(一)和(二)中变量的作用域
(一)声明的所有变量均为全局变量,(二)中,我们仅仅暴露了一个全局变量common(当然,如果你原因可以像mootools那样基于package概念,common.util.stringUtil,comm.util.*)
2,然后我们看一下,(一)中声明带来的问题
(一)中变量的声明散落到任何地方,当我们团队开发项目的时候,不同的开发人员声明的变量或函数可能相同,
因为是全局的,所以会产生冲突问题,浏览器在执行js的时候,同名函数或变量,最后一个将覆盖以前所有同名的变量或函数
举个例子:
张三声明了一个全局变量
var myName="张三";
而李四呢,他也声明了全局变量
var myName="我是李四";
然后他们两个在项目中的不同模块 向 客户问好!
function sayHello()
{
alert("你好,我是"+myName);
}
张三这样说了:
<button οnclick="sayHello()"></button>
李四这样说了:
<img οnclick="sayHello()" src="/welcome.png"></img>
但是客户看到的问候来自谁的呢??
可能是张三,也可能是李四。
如果张三和李四声明了同名函数,但是函数体的具体实现不同,那么张三和李四在使用这个函数时,自以为调用了自己声明的函数,但始终未达到自己想要的效果,或者说代码做了他无法挽回的事情,那么后果就灰常严重了,
四,总结
前几天在看jQuery源码和JavaScript: The Definitive Guide, 5th Edition,学到许多js优化以及js面向对象编程的方法,语言的诞生自有它存在的价值。
本文主要介绍如何避免全局变量及全局函数冲突,我们使用面向对象的方法解决冲突问题,其中借鉴了jQuery和mootools的一些技巧