2013-11-04 165 views
4

在這個簡單的代碼來看看:for循環中的索引變量(_i)?

eat = (x) -> console.log "nom", x 

# dog only eats every second cat 
feast = (cats) -> eat cat for cat in cats when _i % 2 == 0 

feast ["tabby cat" 
     "siamese cat" 
     "norwegian forest cat" 
     "feral cat" 
     "american bobtail" 
     "manx"] 

$ coffee a.coffee 
nom tabby cat 
nom norwegian forest cat 
nom american bobtail 

看來_i變量是當前索引。這是一個功能,錯誤還是NaN?我還沒有聽到任何其他人在談論這件事,所以我想知道是否有某些原因,我不應該在我的代碼中使用它?

回答

14

tldr-again; CoffeeScript的作者剛告訴我I'm right:請勿使用_i

14:29 <jashkenas> You shouldn't use internal variables. 
... 
14:42 <meagar> I was hoping something more deeply involved in the language would be able to put some authority behind that opinion 
14:43 <meagar> ... I was basically hoping for an authoritative "don't do that" 
14:44 <jashkenas> you just got it ;) 
14:44 <jashkenas> for item, index in list -- there's your reference to the index. 

tldr;這最多是undocumented feature,其中功能等效記錄功能存在。因此,應該使用而不是

「少打字」的說法非常可疑;比較:

for x in [1, 2, 3] when _i % 2 == 0 
    console.log "#{_i} -> #{x}" 

for x,i in [1, 2, 3] when i % 2 == 0 
    console.log "#{i} -> #{x}" 

功能,錯誤或喃?

沒有這些東西;這是未定義的行爲。假設是,那麼_i將是用於編譯JavaScript中的迭代的變量。

您絕對不應該使用_i,或者假設_i將被定義。這是一個實現細節,他們可以隨時更改它。如果你的循環嵌套在另一個循環中,它也不會_i;這將是_j_k

最重要的是,你可以這樣做確切的事情沒有依賴於底層實現的JavaSript變量。如果你想與索引循環,只要使用for value,key in array

array = ['a', 'b', 'c'] 

console.log(index) for item, index in array # 0, 1, 2 

具體來說,在你的榜樣:

feast = (cats) -> eat cat for cat, index in cats when index % 2 == 0 
2

無需猜測,或做出假設,什麼Coffeescript一樣。看看編譯後的Javascript。從 '嘗試CoffeeScript的' 標籤:

feast = (cats) -> eat cat for cat in cats when _i % 2 == 0 

產生

feast = function(cats) { 
    var cat, _i, _len, _results; 
    _results = []; 
    for (_i = 0, _len = cats.length; _i < _len; _i++) { 
    cat = cats[_i]; 
    if (_i % 2 === 0) { 
     _results.push(eat(cat)); 
    } 
    } 
    return _results; 
}; 

...

feast = (cats) -> eat cat for cat, index in cats when index % 2 == 0 

產生幾乎相同的JS,沿着或代替的_i可以用來在index只不同。

feast = function(cats) { 
    var cat, index, _i, _len, _results; 
    _results = []; 
    for (index = _i = 0, _len = cats.length; _i < _len; index = ++_i) { 
    cat = cats[index]; 
    if (index % 2 === 0) { 
     _results.push(eat(cat)); 
    } 
    } 
    return _results; 
}; 

這兩個工作,但index使你的意圖更清晰地向人類(包括你的未來自我)。正如其他人所認爲的,避免使用無證實施功能是一種很好的編程實踐 - 除非您確實需要它們。如果你正在做一些有趣的事情,請記錄下來。