0

この CoffeeScript をコンパイルすると:

    funcs = ((=> console.log i) for i in [0..2])                                                                                                                                                                                          

    funcs[0]()  // Prints 3
    funcs[1]()  // Prints 3
    funcs[2]()  // Prints 3

次の JavaScript が生成されます。

    (function() {
      var funcs, i;

      funcs = (function() {
        var _i, _results,
          _this = this;
        _results = [];
        for (i = _i = 0; _i <= 3; i = ++_i) {
          _results.push(function() {
            return console.log(i);
          });
        }
        return _results;
      }).call(this);

      funcs[0]();

      funcs[1]();

      funcs[2]();

      funcs[3]();

    }).call(this);

代わりに次のようになると思います:

          _results.push((function(i) {
             return function() {
              return console.log(i);
          }})(i));

誰かがそれをしていない理由を説明できますか?

4

4 に答える 4

1

ファット アローはthis、すべての変数ではなく、レキシカルにバインドします。doIIFE を使用して変数をキャプチャするために使用します。

funcs =
  for i in [0..2]
    do (i) ->
      -> console.log i
于 2013-03-03T11:00:49.077 に答える
0

さて、CoffeeScriptのドキュメントを見た後、私は自分の質問に答えたと思います。 =>関数を現在の値にバインドするだけですthis。私は、それがすべての変数を現在の値にバインドしていると誤って想定していました。

...そのような機能があればいいのですが。多分->>

于 2013-03-03T10:29:58.733 に答える
0

そのコーヒーをjavascriptに変換すると、スコープをバインドする関数が得られます。問題はそれです:

funcs = (function() {
    var _i, _results,
      _this = this;
    _results = [];
    for (i = _i = 0; _i <= 3; i = ++_i) {
      _results.push(function() {
        return console.log(i);
      });
    }
    return _results;
  }).call(this);

ここでは、変数iがバインドされていますが、関数を呼び出すまでに値は3になり、関数を呼び出すたびに3のままになります。

于 2013-03-03T10:31:57.843 に答える
0

これはクロージャーの仕組みではありません。別の関数スコープから関数を返すと、クロージャーが得られます。

var closure = (function(i) {
    return function() {
        console.log(i);
    };
})(i);

これは、この醜い CoffeeScript を介して実現できます (ここでは太い矢印は必要ありません)。

funcs = ((do (j=i) -> -> console.log j) for i in [0..2])

ただし、これを 1 行で書かないことをお勧めします。

于 2013-03-03T10:20:09.930 に答える