2012-12-03 8 views
7

私は、メンバー関数render()を持っています。この関数は、クラスadd(any)の別のメンバーを呼び出します。これがスニペットです。thisキーワードはtypescriptにあります。バグですか?

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

追加でキーワード「this」を使用すると、タイプはウィンドウになります。私はそれがメンバークラスのインスタンスであると期待しています。

コンストラクタ、メンバ関数、またはメンバアクセサでは、これは含まれるクラスのクラスインスタンス型です。

答えて

3

私はバグだとは思わない。

あなたはもはやrender()機能の範囲内ではなく、each()の範囲内です。

このお試しください:

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

IMO、バグですが、TypeScript言語の定義です。クラス内の "this"は、クラスインスタンス、periodを参照する必要があります。メソッドが呼び出される方法に応じてJavaScriptが "this"が指しているものを変更する方法は、その最悪のミスの1つです(それらの言語でいっぱいです)。 TypeScriptがJavaScriptの本当のスーパーセットになりたければ、通常のメソッドではそれを変更することはできませんが、クラスメソッドではそれを絶対に変更する必要があります。 –

+4

しかし、 'render()'ではなく 'each()'のコールバッククロージャの中にいます。クロージャスコープはJSの基本的な特徴であり、したがってTSです。とにかく、あなた(そしてOP)が好きではないが、確かに意図的で、公開された仕様を満たしているので、定義上はバグ*ではないかもしれません。 SO、IMOにはあまりにも多くの記事が掲載されていますが、彼らのタイトルには明らかな「バグ」があります。それはもっと注意を払って使うべき用語です。 – JcFx

+5

実装上のバグではないという合意がなされました。おそらく(スペック・レベルの)回避策は、別のキーワード、「私」でしょうか? - それ? - 常にクラスインスタンスを指し、問題のメソッドが割り当てられたオブジェクトではありません。 –

16

をJcFxが指摘するように、あなたのthisスコープはeachコールバック内で異なっています。あなたは「太っ矢印」無名関数を使用する場合

しかし、それはあなたが探しているものを手に入れるようにthisためにレキシカルスコープのルールを使用します。

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

は、次のJavaScriptにコンパイル:

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

別のオプションは、希望thisに明示的にbindadd呼び出すことです

+0

+1より洗練された正確なソリューション。 – JcFx

関連する問題