麻雀虽小,五脏俱全:研究一下JavaScript的函数回调机制
“麻雀虽小,五脏俱全”系列
---
1、背景
Javascript中的回调函数,相信大家都不陌生,最明显的例子是做Ajax请求时,提供的回调函数,
实际上DOM节点的事件处理方法(onclick,ondblclick等)也是回调函数。
在使用DWR的时候,回调函数可以作为第一个或者最后一个参数出现,如:
function callBack(result){}myDwrService.doSomething(param1,param2,callBack);//DWR的推荐方式//或者myDwrService.doSomething(callBack,param1,param2);
<html><head><script> var context="全局"; var testObj={ context:"初始", callback:function (str){//回调函数 alert("callback:我所处的上下文中,context="+this.context+",我被回调的方式:"+str); } };//创建一个对象,作为测试回调函数的上下文 testObj.context="已设置"; function testCall(){ callMethod(testObj.callback); callObjMethod(testObj,testObj.callback); } function callObjMethod(obj,method){ method.call(obj,"指定显式对象上下文回调"); } function callMethod(method){ method("通过默认上下文回调"); }</script></head><body><a href="javascript:void(0)" onclick="testCall()">调用测试</a></body></html>
var closureFunc=function(){ testObj.callback();}
<html><head><script> var context="全局"; var testObj={ context:"初始", callback:function (str){//回调函数 alert("callback:我所处的上下文中,context="+this.context+",我被回调的方式:"+str); } };//创建一个对象,作为测试回调函数的上下文 testObj.context="已设置"; function testCall(){ callMethod(testObj.callback); callWithClosure(function(param){testObj.callback(param);}); callObjMethod(testObj,testObj.callback); } function callObjMethod(obj,method){ method.call(obj,"指定显式对象上下文回调"); } function callMethod(method){ method("通过默认上下文回调"); } function callWithClosure(method){ method("通过Closure保持上下文回调"); }</script></head><body><a href="javascript:void(0)" onclick="testCall()">调用测试</a></body></html>
var testObj={ context:"初始", callback:function (str){//回调函数 alert("callback:我所处的上下文中,context="+this.context+",我被回调的方式:"+str); }, caller:function(){ callWithClosure(function(param){this.callback(param);}); }};//创建一个对象,作为测试回调函数的上下文
<html><head><script> var context="全局"; var testObj={ context:"初始", callback:function (str){//回调函数 alert("callback:我所处的上下文中,context="+this.context+",我被回调的方式:"+str); }, caller:function(){ callWithClosure(function(param){this.callback(param);}); var temp=this; callWithClosure(function(param){temp.callback(param);}); } };//创建一个对象,作为测试回调函数的上下文 testObj.context="已设置"; function testCall(){ callMethod(testObj.callback); testObj.caller(); callWithClosure(function(param){testObj.callback(param);}); callObjMethod(testObj,testObj.callback); } function callObjMethod(obj,method){ method.call(obj,"指定显式对象上下文回调"); } function callMethod(method){ method("通过默认上下文回调"); } function callWithClosure(method){ method("通过Closure保持上下文回调"); } function callback(str){ alert("callback:我是定义在外部的全局函数。"); }</script></head><body><a href="javascript:void(0)" onclick="testCall()">调用测试</a></body></html>
var testObj={ that:this, context:"初始", callback:function (str){//回调函数 alert("callback:我所处的上下文中,context="+that.context+",我被回调的方式:"+str); } };
[解决办法]
JavaScript 中的 this 对象是可变的,随着绑定对象的不同而发生变化,不像 Java 中的 this 是不可变对象。
var me = this; 这种方式在闭包函数中很常用,借由一个变量来引用当前的对象,在闭包中仍然可以获得上一上下文中的 this 对象,
而不是闭包执行时的上下文对象。
[解决办法]