我正在使用RequireJs和生产版本使用r.js组合/缩小和uglify-ing,但是遇到了与它如何处理我的一个FOR循环相关的错误。
我关闭了r.js构建的所有优化,所以现在只将代码合并到一个文件中,但不是缩小/ uglifying;然而,这个bug仍然存在。
原始(简化)代码:
var myArray = ['item1', 'apple', 'item2', 'item3', 'bread', 'etc'];
//remove items from array according to some complex logic
for (var i = 0; i < myArray.length; i++) {
var cur = myArray[i];
if (cur.indexOf('item') === 0) { //if starts with "item" remove it
myArray.splice(i, 1);
i--; //*IMPORTANT* Move index back to avoid skipping next item
continue;
}
//do unrelated processing
}
//now use the array
alert(myArray);
原始代码输出:
['apple', 'bread', 'etc']
此代码在编写时正常工作。但是,当我通过r.js(使用optimize:“none”)运行它时,它输出的代码不能按预期工作:
r.js输出代码:
var myArray = ['item1', 'apple', 'item2', 'item3', 'bread', 'etc'];
var _loop = function _loop(_i) {
var cur = myArray[_i];
if (cur.indexOf('item') === 0) {
myArray.splice(_i, 1);
_i--;
return 'continue';
}
}
for (var i = 0; i < myArray.length; i++) {
var _ret = _loop(i);
if (_ret === 'continue') continue;
}
alert(myArray);
r.js代码输出:
['apple', 'item3', 'bread', 'etc']
正如您所看到的,代码几乎相同,但是因为r.js将我的for循环移动到一个函数中,所以在删除/拼接一个值并移动之后我无法改变索引返回索引,对索引的更改将完全丢失,并跳过数组中的下一个项目。
解决方法
我可以将索引循环回到前面,所以我不需要改变索引,但是我正在执行其他需要按顺序完成的计算(从前到后)。另外,我担心这个漏洞会在未来隐藏在我的代码中。
问题
这是r.js应该如何工作(我错过了一个简单的设置)?
我是否采用反模式进行编码并且应该改变我的方法?
谢谢!
答案 0 :(得分:0)
<强>更新强>
正如评论中所讨论的,解决方案是将i
的声明从for
循环结构中拉出来:
var i;
for (i = 0; i < myArray.length; i++) {
// ...
}
意见:自there is no functional difference两种声明i
的方式之后,有趣的是它们被r.js解释为不同。
当然,您也可以选择Array.prototype.filter
完全避开问题:
var myArray = ['item1', 'apple', 'item2', 'item3', 'bread', 'etc'];
myArray = myArray.filter(item => ! /^item/.test(item));
console.log(myArray);
&#13;
使用Array.prototype.forEach
:
var myArray = ['item1', 'apple', 'item2', 'item3', 'bread', 'etc'];
/** @return {boolean} */
function filterFn(item, index) {
console.log(`Doing additional stuff with: myArray[${index}] = ${item}`);
return ! /^item/.test(item);
}
myArray = myArray.filter(filterFn);
myArray.forEach((item, index) => {
console.log(`After: myArray[${index}] = ${item}`);
});
&#13;