我正在玩 CoffeeScript (我是这种“语言”的新手)并尝试了一个非常基本的示例:
x = [1, 2, 3]
for element in x
console.log(element)
这正如它所说的那样,对于将其输出到控制台的每个元素。只是当我仔细研究了它编译的 Javascript 后,我才无法理解他们为什么这样做:
(function() {
var element, i, len, x;
x = [1, 2, 3];
for (i = 0, len = x.length; i < len; i++) {
element = x[i];
console.log(x[i]);
}
}).call(this);
这样做是否会更好并且更自然:
for(i = 0; i < x.length; i++)
{
console.log(x[i]);
}
为什么 CoffeeScript 编译成这样看起来不自然的方式?如果我在 Javascript 中编写相同的代码,我会遵循我所做的方法,但我可能会错,因为我这样做的方式(Javascript)不是最有效或“自然”的,而 CoffeeScript 方法是更好的解决方案。
最佳答案
基本上,您期望 CoffeeScript 编译器执行非常复杂的操作。
考虑这个 CoffeeScript:
for a in x
console.log(a)
for b in a
console.log(b)
callFunc(b)
这会转换为:
for (i = 0, len = x.length; i < len; i++) {
a = x[i];
console.log(a);
for (j = 0, len1 = a.length; j < len1; j++) {
b = a[j];
console.log(b);
callFunc(b);
}
}
很容易看出原始 CoffeeScript 如何与生成的 JavaScript 相对应:
for [variable] in [array]
[body]
变成了
for (var [letter] = 0, len = [array].length, [letter] < len; [letter]++) {
[variable] = [array][[letter]]
[body converted to JavaScript]
}
因此,当将 for
理解式翻译成 JavaScript 时,(几乎)编译器需要担心的就是这个简单的对应关系,然后它可以向内工作并将主体作为单独且独立的操作进行处理.
此外,len = [array].length
缓存也是为了提高性能。这看起来并不完全令人愉快,而且大多数人不会以这种方式编码,但生成漂亮的 JavaScript 并不是 CoffeeScript 的主要目标。它生成高效的代码,假设人们通常不会阅读生成的 JavaScript。
您的建议是采用原始代码并将其转换为:
for (i = 0; i < x.length; i++) {
console.log(x[i]);
for (j = 0; j < x[i].length; j++) {
console.log(x[i][j]);
callFunc(x[i][j]);
}
}
为了将 console.log(b)
转换为 console.log(b);
,编译器不需要知道任何事情 关于该语句周围的代码。为了将 console.log(b)
转换为 console.log(x[i][j]);
,编译器必须采用所有内容 围绕该声明考虑在内。它会给编译器带来极其复杂的工作,并且不会真正提供任何好处。
关于javascript - 为什么 CoffeeScript 会编译为不惯用的 JavaScript?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28742969/