簡體   English   中英

為什么CoffeeScript可以編譯為通用JavaScript?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM