本来是回别人的帖子,遭遇刷楼被禁,就发这吧。
先把代码贴出来
var __method = this ;
return function (event) {
__method.call(object, event || window.event);
}
}
解构一下
Function.prototype.bindAsEventListener = function (object){...}
// 在Function原型上增加prototype,则所有function()都能继承到这个方法。例如
function z();
alert(z.bindAsEventListener);
// 做一个指针,指向Function<--请注意是Function而不是bindAsEventListener
var __method = this ;
return function (event) {
__method.call(object, event ¦ ¦ window.event);
}
// 返回一个函数。请注意是返回一个函数而不是函数结果,否则函数内部并没有返回结果不就永远成了undefined了
call()要理解。这个说起来有点麻烦。举个例子:
val : " a " ,
run : function (val){
alert(val)
}
}
var b = {
val : " b "
}
a.run.call(b, " c " );
// a的run方法召唤b来调用它,参数是"c"。b并没有run方法。相当于b.run = c.run;b.run("c");的这么过程。
根据bindAsEventListener字面意思,用上面这些代码写个例子
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head >
< title > Untitled Page </ title >
< script type ="text/javascript" >
Function.prototype.bindAsEventListener = function (object) {
var __method = this ;
return function (event) {
__method.call(object, event || window.event);
}
}
</ script >
</ head >
< body >
< div id ="test" style ="background-color:#ccc; padding:20px;" > aaaaaaaaaaaaaaaaaaaaaaa </ div >
< script type ="text/javascript" >
// 方便起见,重新封装getElementById。自然它也具备bindAsEventListener方法
function $(id){ return document.getElementById(id); }
// 定义一个事件监听方法
function show(){ alert(arguments[ 0 ]); }
// 获取Element
var div = $( " test " );
// 绑定事件作为div的事件监听器,在onclick时触发 如果使用addEventListener可绑定多个方法。
div.onclick = show.bindAsEventListener(div);
</ script >
</ body >
</ html >
在这个例子中,onclick触发show方法在bind div后返回的一个方法,即 function(event);
这个方法召唤div来实现__method方法,并以当前的事件作为参数传递过去。 __method.call(object, event || window.event);
前面强调过__method指向的是Function,在这里也就是实例show
show通过arguments[0]来获取传递过来的第一个参数,也就是event。所以,可以随意修改show并能简单第将这个方法绑定到每一个事件中。当然,如果采用 addEventListener方法来绑定事件会更灵活。
简便的维护,简洁的代码,我想这就是这个bind方法的初衷。
1.4下多了个return我想没有太多奥妙,应该是方便show()返回值。
没用过prototype框架,也没有上下文,差不多就这意思吧。
-------------------------
补充return的问题
上面讲了,return function(event) 返回的是一个函数而不是函数的执行结果。
相当于
var test = function(event){...}
return test;
而不是
return test();
所以在function(event)内部加不加return对bind来说是没有区别的,因为这个function(event)并没有执行。
而我在文章中提到的那个show函数才是真正执行的方法;换成show的话,可以改写成
1.3
return function(event) {
show(event);
};
1.4
return function(event) {
return show(event);
};
div.onclick = function(event) {
return show(event);
};
象onclick这种void操作,此时return与否根本无关紧要。
做一个1.4的例子
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head >
< title > Untitled Page </ title >
< script type ="text/javascript" >
Function.prototype.bindAsEventListener = function (object) {
var __method = this ;
return function (event) {
return __method.call(object, event || window.event);
}
}
</ script >
</ head >
< body >
< div id ="test" style ="background-color:#ccc; padding:20px;" > aaaaaaaaaaaaaaaaaaaaaaa </ div >
< script type ="text/javascript" >
function $(id){ return document.getElementById(id); }
var ref = null ;
var div = $( " test " );
function show(){ return arguments[ 0 ]; }
div.onclick = function (event){
this .innerHTML = " Event is " + show.bindAsEventListener(div)(event || window.event);
}
</ script >
</ body >
</ html >
仅在某些特殊场合需要这个值的return