[英]Why does CoffeeScript compile to unidiomatic JavaScript?
我正在玩Coffee腳本(我是這種“語言”的新手),並嘗試了一個非常基本的示例:
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]);
}
為什么咖啡腳本會編譯為看起來不自然的方式? 如果我用Javascript編寫了相同的代碼,那么我會遵循我做的方法,但是我做錯的方法(Javascript)可能不是最有效或“自然的”,而咖啡腳本方法是錯誤的,這可能是錯誤的更好的解決方案。
基本上,您希望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
comprehension轉換為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]);
,編譯器將不得不考慮該語句周圍的所有內容 。 這將使編譯器執行起來非常復雜,並且不會真正帶來任何好處。
首先,默認情況下,CoffeeScript將所有內容構建在一個閉包中,即以下幾行:
(function() {
}).call(this);
閉包可防止變量泄漏出腳本。 如果要將腳本導出為全局腳本,則需要將其顯式附加到全局腳本,例如window
。
接下來是這一行:
var element, i, len, x;
最好在使用var
之前聲明var
(至少根據jslint )。
您對x的定義當然是:
x = [1, 2, 3];
現在循環:
for (i = 0, len = x.length; i < len; i++) {
element = x[i];
console.log(x[i]);
}
首先定義len
可以防止循環不斷查找x.length
是什么。 僅有三個項目的速度差異不是很大,但是有一個10k的數組,很好...
console.log
很明顯,但是定義了element
變量,因為這是您在編寫循環時指定的變量的名稱。 而且它使用i
而不是element進行迭代主要是因為使用i
進行迭代是標准做法。
因此,您會看到一切都有正當的理由,盡管有些口味有些冗長。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.