2013-11-04 4 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 

IT는 _i 변수는 현재 인덱스 것 같다. 이 기능, 버그 또는 NaN입니까? 다른 사람이 이것에 대해 이야기하는 것을 듣지 못했기 때문에 코드에서 사용해서는 안되는 이유가 있는지 궁금합니다.

답변

14

tldr- 다시; 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}" 

기능, 버그, 또는 NaN이 있습니까?

정의되지 않은 동작입니다. 이라고 가정하면 _i은 컴파일 된 JavaScript의 반복에 사용되는 변수가됩니다.

_i을 사용하거나 _i을 정의해야합니다. 구현 세부 사항이며 언제든지 변경할 수 있습니다. 루프가 다른 루프에 중첩되어 있으면 _i이되지 않습니다. 그것은 _j 또는 _k

가 가장 중요한 것은, 당신이 기본이되는 구현의 기능인 자바 스크립트를 변수에 의존없이 정확한 것은 을 할 수있을 것입니다. 당신은 인덱스 루프를 원하는 경우에, 다만 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을 살펴보십시오. '시도 커피 스크립트'탭에서 :

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 

는 함께 또는 _i 대신에 사용된다 index 만 다를뿐 거의 동일한 JS를 생성한다.

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은 (미래의 자기 포함) 인간에게 당신의 의도를 명확합니다. 그리고 다른 사람들이 주장한 것처럼 실제로 문서화되지 않은 구현 기능을 사용하지 않는 것이 좋은 프로그래밍 습관입니다. 그리고 우스운 일을하는 경우 문서화하십시오.