2013-04-05 84 views
3

我在寫一些JavaScript代碼。我對這個關鍵詞有點困惑。如何訪問dataReceivedHandler函數中的記錄器變量?Javascript「this」scope

MyClass: { 
    logger: null, 
    init: function() { 
     logger = LogFactory.getLogger(); 
    }, 
    loadData: function() { 
     var dataReceivedHandler = function() { 
      // how to access the logger variable here? 
     } 

     // more stuff 
    } 
}; 

回答

6

假設loadData被稱爲像這樣:

MyClass.loadData(); 

則:

loadData: function() { 
    var self = this; 
    var dataReceivedHandler = function() { 
     self.logger ... 
    } 

    // more stuff 
} 
9

你可以這樣做的loadData函數裏面的東西訪問你的對象......

MyClass: { 
    logger: null, 
    init: function() { 
     this.logger = LogFactory.getLogger(); 
    }, 
    loadData: function() { 
     var self = this; 
     var dataReceivedHandler = function() { 
      // how to access the logger variable here? 
      self.logger.log('something'); 
     } 

     // more stuff 
    } 
}; 
3

Becaus e dataReceivedHandler是一個匿名函數,this將引用全局作用域上的窗口對象。我想你可以繞過這兩條路。

一)內部loadData創建一個變量來保存它的上下文然後用它裏面dataReceivedHandler這樣:

loadData: function() { 
    var self = this; 
    var dataReceivedHandler = function() { 
     console.log(self.logger); 
    } 

    // more stuff 
} 

b)使用applycall更改匿名函數的上下文。

loadData: function() { 
    var dataReceivedHandler = function() { 
     console.log(this.logger); 
    } 
    // more stuff 
    dataReceivedHandler.call(this); // by passing this as the first argument we make sure the context of the excuted function is our current scope's this 
} 

由於性能和內存使用優化,我更喜歡選項B,但兩者都可以正常工作。

+1

_「由於dataReceivedHandler是一個匿名函數,它將引用全局範圍上的窗口對象。」_ - 當您通過名稱「dataReceivedHandler」引用它時,它不是匿名的。匿名或不是'this'的值取決於函數是如何被調用的,而不是它如何定義的(正如你大概知道給出你的第二個例子)。請注意,只有在調用'loadData()'方法將'this'設置爲'MyClass'對象時,您的答案中的兩種方法纔會起作用。 – nnnnnn 2013-04-05 00:32:39

+1

當聲明一個沒有返回變量名稱的函數('function(){}'而不是'function name(){}')時,這就是你所說的匿名函數。匿名函數的上下文將始終是'window',除非被諸如'call'或'apply'之類的方法覆蓋。我錯了嗎?如果是這樣,請舉例說明否則。 – iMoses 2013-04-05 00:35:55

+0

我正在糾正自己。如果匿名函數是對象(名稱空間)的一部分,只要直接從該對象執行該方法,就會引用該對象。 – iMoses 2013-04-05 00:37:41