Coffeescript for循环中的索引变量(_i)?
请看以下简单代码:Coffeescript for循环中的索引变量(_i)?,coffeescript,undefined-behavior,Coffeescript,Undefined Behavior,请看以下简单代码: 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
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"]
似乎_i变量是当前的索引。这是特性、bug还是NaN?我没有听到其他人谈论过这个,所以我想知道是否有什么原因我不应该在我的代码中使用它?tldr;《咖啡脚本》的作者刚刚告诉我:不要用我 功能、bug还是NaN 这些都不是;这是未定义的行为。您假设_i将是编译JavaScript中用于迭代的变量 你绝对不应该使用_i,或者假设_i将被定义。这是一个实现细节,他们可以随时更改。如果你的循环嵌套在另一个循环中,它也不会是i;它将是_j或_k等 最重要的是,您可以在不依赖底层实现的JavaSript变量的情况下完成这项工作。如果要使用索引循环,只需使用值,在数组中键入: 具体来说,在您的示例中:
feast = (cats) -> eat cat for cat, index in cats when index % 2 == 0
无需猜测或假设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;
};
生成几乎相同的JS,不同之处在于索引与_i一起使用或代替_i
这两种方法都有效,但索引让你们的意图对人类更清晰,包括你们未来的自我。正如其他人所说,避免使用未记录的实现特性是一种很好的编程实践,除非您真的需要它们。如果你在做一些有趣的事情,记录下来
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
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
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;
};