太い矢印はさまざまな設定で使用できますが、どういうわけか、常に必要なインスタンスにバインドされるとは限りません。
1 に答える
ファットアローは3回バインド
- メソッド宣言時
- メソッド内で関数を宣言するとき
- グローバルコンテキストで関数を宣言するとき
1. メソッド宣言時
Coffeescript コンパイラがクラス宣言内で次の構文パターンに遭遇した場合
class A
somemethod: (paramlist) =>
これにより、クラス A のコンストラクター内に次のコードが生成されます。
this.somemethod = __bind(this.somemethod, this);
つまり、そのインスタンスの定義は、関数のバインドされたバージョンで初期割り当てを上書きしています
2. メソッド内で関数を宣言する場合
メソッド内で太い矢印を使用して関数を定義すると、Coffeescript コンパイラは自動的にクロージャーを作成し、外側のメソッドのthisを変数 _thisにシャドウします。内部関数内で@を参照する と、生成された JavaScript コードで変数_thisが使用されます。
somemethod: ->
=> @someCall()
そして、これは対応するJavascriptです
A.prototype.somemethod = function() {
//_this references this
var _this = this;
return function() {
//and _this is now used within the inner function
return _this.someCall();
};
};
太い矢印のない関数の定義では、そのクロージャーは作成されません。
3. グローバルコンテキストで関数を宣言する場合
このように自由浮動関数を定義すると(別の関数/メソッド内ではなく、クラス内のメソッドとして意味します)
foo = => @bar
次に、対応するJavascriptは次のようになります
var foo,
_this = this;
foo = function() {
return _this.bar;
};
ここでも興味深いのは、thisが _this に割り当てられていることです。これにより、 fooの定義が_thisを閉じることができます。
ただし重要な部分は、これが常に実行環境のグローバル コンテキストであるということです。ブラウザを使用している場合は、window オブジェクトになります。node.js を実行している場合は、実行中のモジュールになります。
警告:とにかく、グローバル コンテキストにアクセスする関数を定義しないでください。これは問題を引き起こします。