1

我想知道 CoffeeScript 中的范围理解编译成的 JavaScript 略有不同。生成的 JavaScript 有什么不同之处吗?

按整数步迭代范围

numbers = (i for i in [start..end] by 2)

编译成:

for (i = start; i <= end; i += 2) {
  _results.push(i);
}

但是当通过小数步迭代时

numbers = (i for i in [start..end] by 1/2)

生成更复杂的 JavaScript:

for (i = start, _ref = 1 / 2; start <= end ? i <= end : i >= end; i += _ref) {
  _results.push(i);
}

那么为什么会有这个附加start <= end条件呢?

4

3 回答 3

1

Coffeescript 并不完全知道表达式 1/2 的计算结果。它可能是 Math.random() - .5,它取决于脚本的特定运行。

因此,Coffeescript 不可能知道 step 是负数还是正数,所以它只是根据 start 和 end 的相对位置而不是常量 step 的符号来键入条件。

于 2012-04-12T20:01:04.353 回答
1

如果你只是这样做,你会得到同样复杂的代码numbers = (i for i in [start..end])。这是因为当开始或结束是变量时,CoffeeScript 不知道范围的方向。编译器有一个特殊的优化,如果提供了一个常量步骤,它将输出更简单的代码,但不幸的是 1/2 被视为表达式而不是常量。

于 2012-04-12T20:53:41.043 回答
1

这是常数与表达式,而不是整数与分数。当 step 是一个常量(例如2)时,CoffeeScript 在编译时知道是否step为正,并为此输出正确的代码。当 step 为表达式(如1/2)时,需要在运行时判断是否为正。

不幸的是,CoffeeScript 似乎将小数识别为表达式,而不管它们是如何编写的(0.51/2),所以没有简单的方法可以避免这个问题。

于 2012-04-13T04:49:03.057 回答