Ajax的call方法

被以下问题郁闷了下。下面比较抽象简述下这个问题。

index.html文件

Test

test.js文件:

/**
  * 定义一个无类型的对象listInfo
  */
var listInfo = 
{
     // 属性info,为对象类型
     info : {
         name : "ljlwill"
     },

    // 方法getName
     getName : function()
     {
          // 我这个例子这样来设置setName,好像“蛮干”哈,现在我只是简化和抽象,实际项目就是要用这些规则
          Ajax.call(this.setName);

          alert(this.info["name"]);
     },

    // 方法setName
    setName: function(name)
    {
        this.info["name"] = name;    // 大家注意这个this
    }
}


/**
  * 定义无类型的Ajax对象
  */
var Ajax = 
{
     // 创建XMLHttpRequest对象
    createXMLHttpRequest : function() 
   {
        var xhr;

        if (window.ActiveXObject)
        {
             var versions = ['Microsoft.XMLHTTP', 'MSXML6.XMLHTTP', 'MSXML5.XMLHTTP', 'MSXML4.XMLHTTP', 'MSXML3.XMLHTTP', 'MSXML2.XMLHTTP', 'MSXML.XMLHTTP'];

             for (var i=0; i< versions.length; i++)
             {
                  try
                  {
                       xhr = new ActiveXObject(versions(i));
                       break;
                  }
                   catch(ex)
                  {
                       continue;
                  }
             }
             
        }
        else
        {
              xhr = new XMLHttpRequest();
        }
    
        return xhr;
   },

   // call方法
   call : function(callback)
   {
       var xhr = this.createXMLHttpRequest();
       
       // 以下也一切从简
       xhr.open("GET", "index.php", true);  //异步
       
       xhr.onreadysatechange = function()
       {
           // 完成
           if (xhr.readySate == 4) 
           {
               swith (xhr.status) 
               { 
                   case : 200    // OK
                      if (typeof(callback) == "function")
                      {
                           callback.call(this, "ljlwill -- from Ajax");   // 将自身绑定到另外一个对象执行
                      } 
               }

               xhr = null;  // 销毁
           }

       }
       
       if (xhr != null) xhr.send(null);
   }

}

这时,我本意要,点击那个Test链接,先弹出“ljlwill",然后在点击一次的时候是弹出“ljlwill -- from Ajax",可是却不论如何点击,都是弹出"ljlwill"。listInfo对象的setName没有执行?里面加个alert,证明是有执行的。

其实,是这个call方法”捣鬼“。

在JavaScript中,将函数自绑定到另外一个对象上执行,有appliy和call方法,它们只是在参数方面有所不同(具体可相关资料,这里不详述)。

Function.prototype.call(thisArg, [arg1, [arg2, ] ...]),所有函数的内部this指针都会指向thisArg,从以上代码中这个thisArg为Ajax对象,非listInfo对象,这样当然改变不了name值了!

所以,把那callback.call(this, "ljlwill -- from Ajax")该为callback.call(listInfo, "ljlwill -- from Ajax"),问题解决。只是这样有一定的隐患,比如listInfo未定义,或改名,牵动的东西还蛮多!所以,可以就让Ajax对象来运行这函数,而函数的方法内部指明关联哪个对象!

以上也是个人愚见,不是有否不足,或不对,期待讨论~

发表回复

您的电子邮箱地址不会被公开。