2015-05-08 37 views
0

我在我的javascript代碼中有this範圍的兩個大問題。 創建setAJAXGet對象後,回調函數丟失,無法正確調用。所以,而不是打電話this.funct我設置ajax.parent = this;並致電this.parent.funct - 工作正常。xmlhttprequest中的「this」範圍的雙重問題javascript

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(); 
} 

我可以通過修改setAJAXGet()傳遞對象給processAsyncData作爲參數解決這個問題,但它看起來醜陋。

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(); 
} 

我相信你知道更優雅的解決方案。

+2

我建議你閱讀這篇關於'this'值如何設置的入門書:http://stackoverflow.com/questions/28016664/when-you-pass-this-as-an-argument/28016676# 28016676 – jfriend00

+0

爲什麼不把經典的'var self = this'放在函數的頂部? – Mathletics

+0

@Mathletics我應該在哪裏放'var self = this'? –

回答

0

很難遵循你的代碼的目標,但你需要在Javascript中學習的主要內容是函數內的this的值由函數的調用方式控制。這讓Javascript感到困惑,直到你充分注意到所有重要的是函數的調用方式。如何聲明事物並不重要,只是如何調用它們。

當你做這樣的事情:

get.funct = this.processAsyncData; 

什麼被投入get.funct是一個指針processAsyncData方法。根本沒有連接到get.funct中的this值。因此,稍後您撥打電話get.funct()時,它將不會與呼叫this. processAsyncData()相同。 this的值將丟失。

這就是.bind()派上用場。你可以閱讀.bind here。它所做的是創建一個臨時函數存根,以重新附加值this,以避免上述分離。所以,你可以使用這樣的:

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

然後,當你調用get.funct(),它會產生完全一樣的函數調用和this價值this.processAsyncData()會因爲.bind()創造了一個功能存根自動重新連接期望值爲this

正如我在之前的評論中發佈的,有一個很好的總結,說明this的值在這個其他答案中是如何控制的:When you pass 'this' as an argument

請注意,我提出的解決方案與您在評論中提到的不同。我建議你在這個過程中儘早解決問題,這樣任何人都可以隨時調用.funct方法,而無需做任何特殊的事情。