在大口仔的随笔里面,曾提到过多种javascript中的this用法。然而有时候this可能绑定的不是我们真正想绑定的那个对象,而我们又不得不用它来传递一些东西的时候,采用别名可能是一个不错的选择,下面的例子会说明我的问题。
我要做一个类,来管理页面上的一些html对象,这个类可以动态添加索要管理的对象,并改变所管理对象的一些性质,例如它的onclick事件。就拿onclick来说吧,如果我希望得到被管理对象的一些数据,例如id,也想得到管理者的一些属性,例如所管理对象的数量,那采用this就会发生一些小问题。
(用到了prototype.js脚本库,简化一些操作,大家可以很容易摆渡到)。
页面代码:
Code
1<html xmlns="http://www.w3.org/1999/xhtml" >
2<head runat="server">
3 <title>Untitled Page</title>
4 <script src="../AsangJS/prototype.js" language="javascript" type="text/javascript" charset="gb2312"></script>
5 <script src="../AsangJS/test.js" language="javascript" type="text/javascript" charset="gb2312"></script>
6
7 <script language="javascript" type="text/javascript" charset="gb2312">
8
9 function init(){
10
11 var oneManager=new Mangager("oneManager");
12 oneManager.add($("aDiv"));
13 oneManager.add($("aImg"));
14 }
15
16 </script>
17</head>
18<body onload="init()">
19<%--<body>--%>
20 <form id="form1" runat="server">
21 <div id="aDiv">adsfasdf</div>
22 <img id="aImg" src="../image/chinamap.jpg" alt="ddd" />
23 </form>
24</body>
25</html>
26
1<html xmlns="http://www.w3.org/1999/xhtml" >
2<head runat="server">
3 <title>Untitled Page</title>
4 <script src="../AsangJS/prototype.js" language="javascript" type="text/javascript" charset="gb2312"></script>
5 <script src="../AsangJS/test.js" language="javascript" type="text/javascript" charset="gb2312"></script>
6
7 <script language="javascript" type="text/javascript" charset="gb2312">
8
9 function init(){
10
11 var oneManager=new Mangager("oneManager");
12 oneManager.add($("aDiv"));
13 oneManager.add($("aImg"));
14 }
15
16 </script>
17</head>
18<body onload="init()">
19<%--<body>--%>
20 <form id="form1" runat="server">
21 <div id="aDiv">adsfasdf</div>
22 <img id="aImg" src="../image/chinamap.jpg" alt="ddd" />
23 </form>
24</body>
25</html>
26
脚本代码。
Code
1
2var Mangager=Class.create();
3Mangager.prototype={
4 initialize:function(name){
5 this.managerNAME=name;
6 this.objArray=new Array();
7 },
8 managerNAME:null,
9 objArray:null,
10 add:function(ele){
11 var theIndex=this.objArray.length;
12 this.objArray[theIndex]=ele;
13 ele.onclick=function(){this.dealEle(theIndex,ele);};
14 },
15 dealEle:function(index,eleObj){
16 alert("managerNAME="+this.managerNAME+";manageID="+index+";eleID="+eleObj.id+"!");
17 }
18 }
1
2var Mangager=Class.create();
3Mangager.prototype={
4 initialize:function(name){
5 this.managerNAME=name;
6 this.objArray=new Array();
7 },
8 managerNAME:null,
9 objArray:null,
10 add:function(ele){
11 var theIndex=this.objArray.length;
12 this.objArray[theIndex]=ele;
13 ele.onclick=function(){this.dealEle(theIndex,ele);};
14 },
15 dealEle:function(index,eleObj){
16 alert("managerNAME="+this.managerNAME+";manageID="+index+";eleID="+eleObj.id+"!");
17 }
18 }
注意,以上的脚本代码会在13行处发生问题,在:
ele.onclick
=
function
()
{this.dealEle(theIndex,ele);}
;
处提示为:
。
原因就出在这个this上,因为这里的this被动态邦定到ele上了。那么如何能邦定到 Mangager对象的 dealEle方法上呢,这里我们可以在add函数中给Mangager起个别名,然后就得到了他的dealEle方法引用了,很明显,在function(){this.dealEle(theIndex,ele);};的函数体内,this是指向ele的,为了加深印象,我们把这里的ele参数修改为this。
修改后的脚本代码如下:
Code
1var Mangager=Class.create();
2Mangager.prototype={
3 initialize:function(name){
4 this.managerNAME=name;
5 this.objArray=new Array();
6 },
7 managerNAME:null,
8 objArray:null,
9 add:function(ele){
10 var theManager=this;
11 var theIndex=this.objArray.length;
12 this.objArray[theIndex]=ele;
13 ele.onclick=function(){theManager.dealEle(theIndex,this);};
14 },
15 dealEle:function(index,eleObj){
16 alert("managerNAME="+this.managerNAME+";manageID="+index+";eleID="+eleObj.id+"!");
17 }
18 }
1var Mangager=Class.create();
2Mangager.prototype={
3 initialize:function(name){
4 this.managerNAME=name;
5 this.objArray=new Array();
6 },
7 managerNAME:null,
8 objArray:null,
9 add:function(ele){
10 var theManager=this;
11 var theIndex=this.objArray.length;
12 this.objArray[theIndex]=ele;
13 ele.onclick=function(){theManager.dealEle(theIndex,this);};
14 },
15 dealEle:function(index,eleObj){
16 alert("managerNAME="+this.managerNAME+";manageID="+index+";eleID="+eleObj.id+"!");
17 }
18 }
说明:
Mangager类中,add和dealEle中的this一般指向Mangager对象;
虽然ele.οnclick=function(){theManager.dealEle(theIndex,this);};语句在Mangager类的add方法中,但与具体里面的this并不指向Mangager,而是指向ele对象。要想在其中得到Mangager的引用,需要在add函数内,该语句之外给this(Mangager)指定一个别名,然后在该语句内用这个别名来引用Mangager。
运行效果为:
总结:从上面的代码可以看出来,js中适当时候采用this别名而不是this本身,可以防止某些误邦定现象,达到用户理想的效果。