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

这不是闭包的工作方式。当你从另一个函数作用域返回一个函数时,你会得到一个闭包:

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

这可以通过这个丑陋的 CoffeeScript 来实现(这里不需要粗箭头):

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

我建议不要把它写成一行。

于 2013-03-03T10:20:09.930 回答
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 回答