2012-09-06 101 views
11

我試圖讓一個JavaScript對象運行延遲方法,並且它的.done()調用該同一對象中的函數。我有問題,因爲「this」成爲延遲對象而不是調用它的對象。JQuery延遲更改「this」

PageObject.prototype.successFunction = function() { 
    console.log(arguments); 
    return console.log(this.name + " Success function called"); 
}; 

PageObject.prototype.loadPage = function(url) { 
    return $.when($.mobile.loadPage("pages/" + url)) 
    .done(this.successFunction); 
}; 

var pg = new PageObject(); 
pg.loadPage("test.html"); 

如何發送 「這個」 入successFunction?這個PageObject也將被其他人擴展,所以在運行successFunction時瞭解「this」將非常方便。

看起來很簡單,可能有一個簡單的答案。我正在調查.apply(),但我不確定它是否有幫助。這篇文章在堆棧溢出中有一定幫助,但是我把它放到.done()函數中的那一分鐘。

Functions as parameters (with parameters) -- JavaScript

+1

FWIW,延遲的對象不會改變這個,它只是函數的工作方式。這個值不是由函數定義的方式/位置決定的,而是如何調用的。 –

回答

14

jQuery的proxy將返回綁定到特定的上下文中的功能:

PageObject.prototype.loadPage = function(url) { 
    return $.when($.mobile.loadPage("pages/" + url)) 
    .done($.proxy(this.successFunction, this)); 
}; 

還有ES5的bind其操作類似,但需要在舊的瀏覽器進行勻

PageObject.prototype.loadPage = function(url) { 
    return $.when($.mobile.loadPage("pages/" + url)) 
    .done(this.successFunction.bind(this)); 
}; 

applycall可以執行函數immediatel y與指定的上下文,但proxybind返回一個函數,可以稍後使用或傳遞給其他函數。

+0

夢幻般的答案,這正是我所需要的(並且我瘋狂地試圖弄明白)。我最終使用了你發佈的$ .proxy版本。謝謝! – Chris

2

JavaScript中的this「變量」被稱爲「調用對象」,並且在調用其封閉函數時(而不是在定義時)確定它。它可以設置幾種不同的方式:

  1. 您可以通過使用.運營商(如myObject.myFunction())設置
  2. 您可以通過使用
  3. 你可以(在一個函數的call()apply()方法設置ES5)將其綁定永久使用功能的bind()方法
  4. ,則默認爲全局對象,如果沒有上述方法將它設置爲別的

要理解的重要一點是(除了上面的方法3),所有關於函數在被調用時如何被調用,而不是它如何被引用,而不是它如何被存儲,而不是它被創建的位置。

在你的情況,你傳遞this.successFunction作爲一個函數引用被jQuery調用,但它不會這樣調用它(因爲它只是獲得了函數的引用,而沒有任何有關該函數的信息應該被稱爲)。

有你可以用jQuery的$.proxy()或ES5的.bind()方法使用一些花哨的技巧,但是當它歸結到它,處理它的最直接的方法就是簡單地保留this通過關閉範圍的變量和使用函數包裝:

PageObject.prototype.loadPage = function(url) { 
    var self = this; 
    return $.when($.mobile.loadPage("pages/" + url)) 
      .done(function() { self.successFunction(); }); 
}; 

請注意,我們使用方法1,明確綁定successFunction的調用對象是一樣loadPage的調用對象。它簡短,簡單,清晰,在ES3下工作正常,並且不依賴於jQuery。

+0

對於幕後發生的事情+1,但我傾向於喜歡花哨的技巧,如果可用的話,因爲它保持代碼更清潔。 – Dennis