2012-12-03 59 views
7

我有一個成員函數render()。該函數調用類add(any)的另一個成員。這是片段。打字稿中的這個關鍵字。這是一個錯誤嗎?

render(){ 
    collection.each(this.add); 
} 

如果我在add中使用關鍵字「this」,那麼類型就是窗口。我希望它是成員類的實例。

在構造函數,成員函數或成員存取器中,這是包含類的類實例類型。

回答

3

我不認爲這是一個錯誤。

您不再在render()函數的範圍內,而是在each()的範圍內。

試試這個:

render(){ 
    var that = this; 
    collection.each(that.add); 
} 
+6

IMO,這是一個錯誤,但在TypeScript語言定義。這個「在類內」應該指類實例,句點。 JavaScript根據方法的調用方式改變「this」指向的方式是其最糟糕的錯誤之一(以其中的一種語言)。如果TypeScript想成爲JavaScript的真正超集,它不能改變普通方法,但它可以也絕對應該改變它的類方法。 –

+4

但是你在回調閉包('each()',而不是'render()')中。封閉範圍是JS的基本特徵,因此TS。無論如何,它可能是你(和OP)不喜歡的*特性,但它肯定是故意的,並且符合發佈的規範,所以根據定義它不是* bug *。 SO,IMO上的帖子太多了,他們的標題中顯示出「bug」:這個術語應該更加謹慎。 – JcFx

+5

同意這不是實施中的錯誤 - 只是在規範:-)。也許一個解決方法(在規範級別)將是一個不同的關鍵字 - 「我」? - 那個? - 它總是指向類實例,而不是指向所討論方法的對象。 –

16

由於JcFx指出,你this範圍是each回調中有所不同。

但是,如果使用「胖箭頭」匿名函數,將使用詞法作用域規則this讓你得到你所要查找的內容:

render(){ 
    collection.each((x) => this.add(x)); 
} 

編譯爲以下JavaScript:

X.prototype.render = function() { 
    var _this = this; 
    collection.each(function (x) { 
     return _this.add(x); 
    }); 
} 

另一種選擇是明確的bind電話add到所需this

render(){ 
    collection.each(this.add.bind(this)); 
} 
+0

+1爲了更加優雅和準確的解決方案。 – JcFx