2012-11-02 41 views
1

如果我正在使用此代碼,爲什麼「doStuff」警報的作用域發生變化?有沒有一種方法可以確保範圍是我的對象而不是Window對象?

這是和jsfiddle相同的代碼。

(function ($) { 
    var c$ = {}; 

    c$.TestScope = function() { 

     this.doAjax = function (onComplete) { 
      var self = this; 
      $.ajax({ 
       url: 'badurl', 
       complete: function (data) { 
        alert('doAjax2 self === c$.oTestScope: ' + (self === c$.oTestScope).toString()); 
        onComplete(data); 
       } 
      }); 
      alert('doAjax1 self === c$.oTestScope: ' + (self === c$.oTestScope).toString()); 
     }; 

     this.doStuff = function (data) { 
      var self = this; 
      alert('doStuff self === c$.oTestScope: ' + (self === c$.oTestScope).toString()); 
     } 

    }; 

    c$.oTestScope = new c$.TestScope(); 
    c$.oTestScope.doAjax(c$.oTestScope.doStuff); 
})(jQuery);​ 

回答

5

你應該能夠在你的$.ajax()參數指定this值作爲背景:

var c$ = {}; 

c$.TestScope = function() { 

    this.doAjax = function(onComplete) { 

     alert('doAjax1 this === c$.oTestScope: ' + (this === c$.oTestScope).toString()); 

     $.ajax({ 
      url: 'badurl', 
      context: this, 
      complete: function(data) { 
       alert('doAjax2 this === c$.oTestScope: ' + (this === c$.oTestScope).toString()); 
       onComplete.call(this, data); 
      } 
     }); 
    }; 

    this.doStuff = function(data) { 
     alert('doStuff this === c$.oTestScope: ' + (this === c$.oTestScope).toString()); 
    } 

}; 

c$.oTestScope = new c$.TestScope(); 
c$.oTestScope.doAjax(c$.oTestScope.doStuff); 

編輯我爲這個fiddle並驗證其工作正常。有一個額外的self參數沒有搞亂,或者不得不使用閉包來控制變量。

你缺少的部分是呼叫onComplete.call(this, data)來調用doStuff()

+0

上下文選項似乎只在直接調用函數「context:onComplete」時才起作用。我看不出有什麼方法可以使用此方法來設置默認功能以及回調功能。這裏是與上下文選項http://jsfiddle.net/RW4Ge/2/ jsfiddle。 – bconrad

+0

我知道你已經選擇了你的解決方案,但請看看這個修訂版。它用'this'乾淨地修復你的問題,而不必使用任何額外的閉包或臨時變量。 – slashingweapon

+0

我感謝你的幫助,也許我錯過了一些東西,但你的例子並沒有使用'onComplete'回調。它直接調用'doStuff'。如果你把'this.doStuff(data)'改成'onComplete(data)','(this === c $ .oTestScope)'將返回false。我同意你的語法更清晰。如果我可以使用它,我會使用它。 – bconrad

3

我已經改變了您的代碼,以將對this的引用傳遞給doStuff()代碼。

(function ($) { 
    var c$ = {}; 

    c$.TestScope = function() { 

     this.doAjax = function (onComplete) { 
      var self = this; 
      $.ajax({ 
       url: 'badurl', 
       complete: function (data) { 
        alert('doAjax2 self === c$.oTestScope: ' + (self === c$.oTestScope).toString()); 
        onComplete(data,self); 
       } 
      }); 
      alert('doAjax1 self === c$.oTestScope: ' + (self === c$.oTestScope).toString()); 
     }; 

     this.doStuff = function (data,thisRef) { 
      var self = thisRef; 
      alert('doStuff self === c$.oTestScope: ' + (self === c$.oTestScope).toString()); 
     } 

    }; 

    c$.oTestScope = new c$.TestScope(); 
    c$.oTestScope.doAjax(c$.oTestScope.doStuff); 
})(jQuery);​ 
+1

這很好。我遇到的唯一問題是我總是必須將「thisRef」參數添加到「doStuff」中。我通過添加作爲可選參數並將「自我」設置爲「this」(如果未提供該選項)來解決此問題。這裏是我更新的jsfiddle http://jsfiddle.net/RW4Ge/3/。 – bconrad