Prototype.AjaxRequest的调用堆栈重写问题【摘】

Prototype.AjaxRequest的调用堆栈重写问题

作者:cleverpig





        由于调用AjaxRequest类进行XMLHTTPRequest操作时,this引用(指向当前function所在的对象)会出现了call stack问题,从而指向当前的对象:

错误演示:

var OverWritingDemonstrate=Class.create();
OverWritingDemonstrate.prototype={
        xml_source:'',
        initialize:function(){
        },
        putRequest:function(url,params,callBackFunction){
                var funcHolder=arguments.callee.$;
            var xmlHttp = new Ajax.Request(url,
                        {
                                method: 'get',
                                    parameters: params,
                                requestHeaders:['my-header-encoding','utf-8'],
                                    onFailure: function(){
                                        alert('对不起,网络通讯失败,请重新刷新!');
                                },
                                onSuccess: function(transport){
                                },
                                onComplete: function(transport){
                                        this.xml_source=transport.responseText;
                                        this.showXMLResponse();
                                }
                        });
        },
        //显示xml信息
        showXMLResponse:function(){
                alert(this.xml_source);
        },
        …
}


        这样使用必定找不到showXMLResponse方法,因为在AjaxRequest的onComplete函数中的this指向了当前的function所在的对象xmlHttp,而不是我们的OverWritingDemonstrate类对象。

Fix方法:

        我们可以借鉴一下 《解开JavaScript生命的达芬奇密码》Joshua Gertzen的方法,实现一个ClassUtils类:

//类工具
var ClassUtils=Class.create();
ClassUtils.prototype={
        _ClassUtilsName:'ClassUtils',
        initialize:function(){
        },
        /**
         * 给类的每个方法注册一个对类对象的自我引用
         * @param reference 对类对象的引用
         */
        registerFuncSelfLink:function(reference){
                for (var n in reference) {
                var item = reference[n];                        
                if (item instanceof Function)
                                item.$ = reference;
            }
        }
}


        然后修改一下前面的OverWritingDemonstrate,这里为了达到区分效果的目的,类名取为AjaxWrapper:

//Ajax操作封装类:
//由于调用AjaxRequest类进行XMLHTTPRequest操作时,this引用(指向当前的对象)会出现了call stack问题,从而指向当前的对象。
//所以,对putRequest、callBackHandler、以及callback方法都要使用arguments.callee.$来获得正确的类对象引用
var AjaxWrapper=Class.create();
AjaxWrapper.prototype={
        xml_source:'',
        /**
         * 初始化
         * @param isDebug 是否显示调试信息
         */
        initialize:function(isDebug){
                new ClassUtils().registerFuncSelfLink(this);
        },
        putRequest:function(url,params,callBackFunction){
                var funcHolder=arguments.callee.$;
            var xmlHttp = new Ajax.Request(url,
                        {
                                method: 'get',
                                    parameters: params,
                                requestHeaders:['my-header-encoding','utf-8'],
                                    onFailure: function(){
                                        alert('对不起,网络通讯失败,请重新刷新!');
                                },
                                onSuccess: function(transport){
                                },
                                onComplete: function(transport){
                                        funcHolder.xml_source=transport.responseText;
                                        funcHolder.showXMLResponse();
                                }
                        });
        },
        //显示xml信息
        showXMLResponse:function(){
                alert(funcHolder.xml_source);
        },
        …
}


        这样就避免了发生在调用堆栈中的this重写问题了。

代码下载:

        
demonstrate.rar


相关资源:

         解开JavaScript生命的达芬奇密码
         Prototype JavaScript framework website
         Prototype 快速教学
         Prototype开发手册
 

你可能感兴趣的:(JavaScript,function,xmlhttprequest,reference,prototype,javascript,parameters)