我传入一组错误消息来解析。输入的示例如下:
"An item with this x Id already exists.
An item with this y id already exists.
An item with this barcode already exists.
"
也就是说,字符串实际上是每行上面用\ n分隔的,最后是\ n。
function( msg )
{
alert( "\"" + msg + "\"" );
var aLines = msg.split( /\r?\n+/ );
for ( var i in aLines )
{
if ( !aLines[i] ) { alert( "Error!" ); continue; }
alert( i + ": \"" + aLines[i] + "\"" );
}
}
我把它分成几行,然后遍历这些行。在索引3处没有行和第一个条件触发器。这应该不是空行吗?例如“”
然后循环实际上又将一个元素变为4,并显示函数的内容。
我得到了 - 五个警告:
0: "An item with this x Id already exists."
1: "An item with this y id already exists."
2: "An item with this barcode already exists."
Error!
最后一个是最离奇的:
hasObject: "function(o) {
var l = this.length + 1;
... more lines ...
}
我不明白这里发生了什么。为什么要迭代一个元素呢?为什么最后一个元素是一个函数?并且不应该偏移3是一个空字符串?那就是我不应该警告“错误!”这里。
答案 0 :(得分:5)
Never loop over an array with for...in.
以任意顺序迭代对象的可枚举属性。
答案 1 :(得分:1)
正如jbabey所说,在Javascript中使用for .. in
循环是有风险且不确定的(随机顺序 - 有时)。您最常用它来解析关联数组中的对象。
但是,如果您坚持保留for .. in
,请将for
的内部包含在if
块中,如下所示:
for (var i in aLines)
{
if(aLines.hasOwnProperty(i))
{
// ... Do stuff here
}
}
否则,只需将其更改为经典的增量for
循环即可消除该错误:
for (var i = 0; i < aLines.length; i++)
{
if ( !aLines[i] ) { alert( "Error!" ); continue; }
alert( i + ": \"" + aLines[i] + "\"" );
}
答案 2 :(得分:1)
您应该对数组使用常规for循环,因为for-in还将返回Array对象中的所有其他属性键。这就是为什么你看到“hasObject”(在我的浏览器中,我之后会看到更多):因为你的数组有“hasObject”函数,所以当你枚举所有Array的属性时,就会出现这种情况。
正确的for循环:
for ( var i = 0, ii = aLines.length; i<ii; i++ )
{
if ( !aLines[i] ) { alert( "Error!" ); continue; }
alert( i + ": \"" + aLines[i] + "\"" );
}
以下是使用for循环替换for-in循环的代码,它按预期工作:
答案 3 :(得分:0)
您最终获得了Error!
,因为拆分为您提供了空行""
,当您使用if(!aLines[i])
进行检查时,它会返回true
,因为它是空的/空/一无所获。你可以在fiddle中查看它,从末尾删除空行,它不会超过数组4次。
我还提供了以下显示警告的代码:
var a="";
if(!a){
alert("!a");
}