0
var xhr=new XMLHttpRequest();
xhr.open('GET','example.php');
xhr.myVar=0;
xhr.onreadystatechange=function(){
  this.myVar=this.responseText.length;
  var s=this.readyState+":"+this.myVar+":"+this.responseText;
  document.getElementById('x').innerHTML=s;
  };

我在网页上有这个脚本(和一个<p id="x"></p>)。我想附加一个变量以在onreadystatechange函数中使用(显然,在实际代码中,我用它做的事情比我在这里做的更有趣)。

这在我尝试过的浏览器中运行良好,但这让我感到紧张。我应该遵循一个约定吗?例如,带有下划线的自定义变量前缀,或类似的东西?

顺便说一句,附加一个成员变量感觉完全正确:主要的替代方法是使用一个全局变量,我一点也不喜欢(我可能在页面上有两个 XMLHttpRequest 对象)。

4

2 回答 2

2

您可以使用闭包

假设这个 ajax 请求在函数体内部,那么您可以声明myVarusingvar关键字并在onreadystatechange函数内部使用它,就好像它是一个局部变量一样。

function x() {

    ....
    ....

    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'example.php');
    var myVar = 0;
    xhr.onreadystatechange = function() {
        this.myVar = this.responseText.length;
        var s = this.readyState + ":" + myVar + ":" + this.responseText;
        document.getElementById('x').innerHTML = s;
    };

    ....
    ....

}
于 2013-04-01T11:49:13.580 回答
1

你正在做的已经很好了。你没有污染全局范围,附加到你知道你已经在函数中拥有的东西(因为函数 onreadystatechange 被调用并this设置为 XHR 对象)。但是,您可能需要改进以下几点:

  • 你的变量名和现在一样好。如果您想要/需要调用您的变量之一responseText怎么办?
  • 范围界定可能会派上用场。
  • 你可能真的想阅读 XHR 以及如何去做。现在,您的代码无法在 IE7/8 上运行。

因为 XHR 只回调一次,所以很多问题并不适用于此,但想象一下这种情况:你有一个神秘的类C,它有一个名为 的回调feedback,它接受闭包。此回调触发四次,您需要将相同的变量传递给四个回调,而回调不可能更改此变量。您的代码对此进行了分解。微不足道,我知道,但值得在第一枪就做到最好。您也正在遵循 DRY 方法。

我将如何做到这一点:

function callCObject(_c_init_vars, callback) {
  var tempObject = new C(); // Instantiating my "C" object, whatever it may be
  var tCallback = function() {
     callback.apply(this,_c_init_vars);
  }
  tempObject.callback = tCallback;
  tempObject.run();
}

而不是手动实例化C,我会这样做:

var myCallback = function(a,b,c) { console.log(a); console.log(b); };
callCObject([1,6], myCallback);

只是为了证明实现:http: //jsfiddle.net/d3yAg/

于 2013-04-01T12:06:31.823 回答