为什么分数迭代步骤编译成不同于整数步骤的JavaScript

时间:2012-04-12 19:57:35

标签: coffeescript

我想知道稍微不同的JavaScript,它将CoffeeScript中的理解范围编译成。有没有理由为什么在生成的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条件?

3 个答案:

答案 0 :(得分:1)

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

因此,Coffeescript不可能知道该步骤是否为正或负,因此它只是根据开始和结束的相对位置而不是常量步的符号来键入条件。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

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