开发者

Please help me understand this JavaScript code from "Ajax in Action"

I saw this code in Ajax in Action book and there are two things I'm not able to understand (Keep in mind I just started web programming and I'm still trying to understand how JavaScript works).

  1. On line 37 or in function loadXMLDoc, why did the author declared a local variable "var loader=this;" and then used it in the call "net.ContentLoader.onReadyState.call(loader);" instead of just using "net.ContentLoader.onReadyState.call(this);"

  2. Why did the author used "net.ContentLoader.onReadyState.call(loader);", instead of "this.onReadyState();"

    /*
    url-loading object and a request queue built on top of it
    */

    /* namespacing object */
    var net=new Object();

    net.READY_STATE_UNINITIALIZED=0;
 开发者_如何学编程   net.READY_STATE_LOADING=1;
    net.READY_STATE_LOADED=2;
    net.READY_STATE_INTERACTIVE=3;
    net.READY_STATE_COMPLETE=4;


    /*--- content loader object for cross-browser requests ---*/
    net.ContentLoader=function(url,onload,onerror,method,params,contentType){
      this.req=null;
      this.onload=onload;
      this.onerror=(onerror) ? onerror : this.defaultError;
      this.loadXMLDoc(url,method,params,contentType);
    }

    net.ContentLoader.prototype.loadXMLDoc=function(url,method,params,contentType){
      if (!method){
        method="GET";
      }
      if (!contentType && method=="POST"){
        contentType='application/x-www-form-urlencoded';
      }
      if (window.XMLHttpRequest){
        this.req=new XMLHttpRequest();
      } else if (window.ActiveXObject){
        this.req=new ActiveXObject("Microsoft.XMLHTTP");
      }
      if (this.req){
        try{
          var loader=this;
          this.req.onreadystatechange=function(){
            net.ContentLoader.onReadyState.call(loader);
          }
          this.req.open(method,url,true);
          if (contentType){
            this.req.setRequestHeader('Content-Type', contentType);
          }
          this.req.send(params);
        }catch (err){
          this.onerror.call(this);
        }
      }
    }


    net.ContentLoader.onReadyState=function(){
      var req=this.req;
      var ready=req.readyState;
      var httpStatus=req.status;
      if (ready==net.READY_STATE_COMPLETE){
        if (httpStatus==200 || httpStatus==0){
          this.onload.call(this);
        }else{
          this.onerror.call(this);
        }
      }
    }

    net.ContentLoader.prototype.defaultError=function(){
      alert("error fetching data!"
        +"\n\nreadyState:"+this.req.readyState
        +"\nstatus: "+this.req.status
        +"\nheaders: "+this.req.getAllResponseHeaders());
    }


A try/catch statement in ECMA-/Javascript creates a new Context. Technically, this is similar to an eval statement and therefore an eval Context.

The current Scope chain is extended by that newly created "eval Context" and therefore, the Context variable this, would point to a wrong context when just invoked by this.onReadyState();.

By calling net.ContentLoader.onReadyState.call(loader); the author explicitly calls the method onReadyState with the context of the loaded object (and that is what this within the callee is referencing then). A callee is a function (-context...) with was called by a caller (-context).


Long story short, ECMAscripts .call() and .apply() methods allow you to set a specific Context for a function when invoked. This is necessary here, because try/catch creates a new Context and the value of this within the called method would be wrong.


While the above statement is true, it's not responsible here. It's not the Context from try / catch which is the problem , it's furthermore the Context by the created anonymous function

this.req.onreadystatechange=function(){
    net.ContentLoader.onReadyState.call(loader);
}

Using this within that anonymous method would "again" reference a different Context. That is why the author cached the value from this in loader and invokes the method with that cached Context.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜