4

次の簡単なコードを見てください。

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 ですか? これについて他の人が話しているのを聞いたことがないので、コードで使用してはいけない理由があるのだろうか?

4

2 に答える 2

14

tldr-再び; CoffeeScript の作成者は、私が正しいと言ったところです。使用しないでください_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; これはせいぜい、機能的に同等の文書化された機能が存在する文書化されていない機能です。そのため、使用しないでください。

「タイピングが少ない」というあなたの主張は非常に疑わしいです。比較:

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?

これらのどれもありません。それは未定義の動作です。コンパイルされた JavaScript の反復に使用される変数になると想定しています。_i

絶対に使用しないでください。または、が定義される_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
于 2013-11-04T04:03:16.070 に答える
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

indexと一緒に、または代わりに が使用される点のみが異なりますが、ほぼ同じ JS が生成され_iます。

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人間 (未来の自分を含む) に対してあなたの意図をより明確にします。また、他の人が主張しているように、本当に必要な場合を除いて、文書化されていない実装機能の使用を避けることは、プログラミングの良い習慣です。そして、何か面白いことをしている場合は、それを文書化してください。

于 2013-11-06T19:47:15.323 に答える