javascript - 请帮助我理解这段来自 "Ajax in Action"的 JavaScript 代码

标签 javascript ajax this

我在 Ajax in Action 一书中看到了这段代码,但有两件事我无法理解(请记住,我刚刚开始网络编程,但我仍在努力理解 JavaScript 的工作原理)。

  1. 在第 37 行或函数 loadXMLDoc 中,为什么作者要声明一个局部变量“var loader=this;”然后在调用“net.ContentLoader.onReadyState.call(loader);”时使用它而不是仅仅使用“net.ContentLoader.onReadyState.call(this);”

  2. 为什么作者使用“net.ContentLoader.onReadyState.call(loader);”,而不是“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());
    }

最佳答案

ECMA-/Javascript 中的 try/catch 语句创建一个新的 Context。从技术上讲,这类似于 eval 语句,因此也是 eval Context

当前的范围链由新创建的“eval Context”扩展,因此,Context 变量 this,当被 this.onReadyState(); 调用时会指向错误的上下文。

通过调用 net.ContentLoader.onReadyState.call(loader); 作者使用 onReadyState 显式调用方法 onReadyState code>loaded 对象(这就是 callee 中的 this 所引用的对象)。 callee 是一个函数 (-context...),由 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.


虽然上述说法属实,但在此概不负责。这不是来自 try/catch 的上下文,这是问题所在,而且是创建的匿名函数的上下文

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

在该匿名方法中使用 this 将“再次”引用不同的上下文。这就是为什么作者将 this 的值缓存在 loader 中并使用缓存的 Context 调用该方法。

关于javascript - 请帮助我理解这段来自 "Ajax in Action"的 JavaScript 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5407296/

相关文章:

javascript - 唯一属性计数 json

javascript - 使用ajax实时进行大型计数操作

javascript - 可以这样运行多个ajax吗?

jquery - 我如何使用ajax将多个数据从 Controller 发送到页面html

android - 匿名类中的“this”

javascript - XUL MenuItem 在动态添加弹出窗口后消失

javascript - 在一个div中找一个关键字,然后得到冒号后面的字符串,转为变量

javascript - 如何结合 do while 循环和 setInterval 计时器功能

javascript - "is not a function"代码中有另一个不相关的函数时出错

c++ - 'this'指针是否参与虚函数多态行为