双重问题"这个" xmlhttprequest javascript中的范围

时间:2015-05-08 17:49:09

标签: javascript ajax asynchronous callback xmlhttprequest

我的javascript代码中有this范围的两个大问题。 创建setAJAXGet对象后,回调函数丢失,无法正确调用。因此,我没有调用this.funct而是设置ajax.parent = this;并致电this.parent.funct - 工作正常。

function setAJAXGet() {
    this.askServer = function() {
    var ajax = new XMLHttpRequest();
    ajax.parent = this; 
    ajax.contentType = "charset:utf-8";
    ajax.onreadystatechange = function() {
            if (ajax.readyState==4 && ajax.status==200) {
            this.parent.funct(ajax.responseText);
            }
    }
    ajax.open( "GET", this.url+'?'+this.vars, true );
    ajax.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    if (navigator.onLine) ajax.send( null ); else this.functError();
    }
this.functError;
this.funct;
this.vars;
this.url;
}

当我尝试从另一个对象调用setAJAXGet()并且回调函数在该对象内时,事情会变得复杂一些。正确调用回调函数,但对象中的每个其他函数(来自回调函数)都不可见。

function someObject() {
    this.asyncGet = function() {
    var get = new setAJAXGet();
    //do some config here...
    get.funct = this.processAsyncData;
    get.askServer();
    }

    this.someOtherFunction = function() {
    }

    this.processAsyncData = function(ajaxText) {
    // ajaxText is OK
    this.someOtherFunction();
    // this.someOtherFunction is not defined (how so?)
    }

this.asyncGet();
}

我可以通过修改processAsyncData作为参数将对象传递给setAJAXGet()来解决这个问题,但它看起来很难看。

function someObject() {
    this.asyncGet = function() {
    var get = new modifiedSetAJAXGet();
    //do config here...
    get.object = this; // stores 'this' and sends it to callback as argument
    get.funct = this.processAsyncData;
    get.askServer();
    }

    this.someOtherFunction = function() {
    }

    this.processAsyncData = function(object, ajaxText) {
    // ajaxText is OK
    object.someOtherFunction();
    // object.someOtherFunction works just fine
    }

this.asyncGet();
}

我相信你知道更优雅的解决方案。

1 个答案:

答案 0 :(得分:0)

很难遵循代码的目标,但是您需要在Javascript中学习的主要内容是函数中this的值由函数的调用方式控制。这是令人困惑的Javascript,直到你完全了解所有重要的是如何调用函数。事情如何宣布无关紧要,只关系它们的召唤方式。

当你做这样的事情时:

get.funct = this.processAsyncData;

放入get.funct的内容是指向processAsyncData方法的指针。完全不再与this中的get.funct值相关联。因此,当您稍后调用get.funct()时,它将与调用this. processAsyncData()不同。 this的值将丢失。

这是.bind()派上用场的地方。你可以阅读.bind here。它的作用是创建一个临时函数存根,重新连接this的值,以便不会发生上述分离。所以,你可以像这样使用它:

get.funct = this.processAsyncData.bind(this);

然后,当您调用get.funct()时,它将生成与this完全相同的函数调用和值,因为this.processAsyncData()已创建函数存根自动重新附加所需的.bind()值。

正如我在之前的评论中所发表的那样,在另一个答案中this如何控制this的价值有一个很好的总结:{/ 3}}。

请注意,我提出的解决方案与您在评论中提到的解决方案不同。我建议您在流程的早期解决问题,以便任何人都可以随时调用.funct方法,而无需执行特殊操作。