0

我传入一组错误消息以进行解析。一个示例输入是:

"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 ...
}

我不明白这里发生了什么。为什么它要遍历另一个元素?为什么最后一个元素是函数?offset 3 不应该是一个空字符串吗?那就是我不应该警告“错误!” 这里。

4

4 回答 4

5

永远不要使用 for...in 循环遍历数组。

以任意顺序迭代object的可枚举属性。

为什么在数组迭代中使用“for...in”是个坏主意?

于 2012-10-19T19:13:17.260 回答
1

正如 jbabey 所说,for .. in在 Javascript 中使用循环是有风险且不确定的(有时是随机顺序)。您最常使用它来解析关联数组中的对象。但是,如果您坚持保留,请用这样的块for .. in包裹 的内部:forif

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]  + "\"" );
}
于 2012-10-19T19:16:46.927 回答
1

您应该对数组使用常规 for 循环,因为 for-in 还将返回 Array 对象中的所有其他属性键。这就是为什么您会看到“hasObject”(在我的浏览器中,之后我会看到更多):因为您的数组具有函数“hasObject”,所以当您枚举数组的所有属性时,就会出现这种情况。

正确的for循环:

  for ( var i = 0, ii = aLines.length; i<ii; i++ )
  {
    if ( !aLines[i] ) { alert( "Error!" ); continue; }
    alert( i + ": \"" + aLines[i]  + "\"" );
  }

这是用 for 循环替换 for-in 循环的代码,它按预期工作:

http://jsfiddle.net/SamFent/4rzTh/

于 2012-10-19T19:21:53.410 回答
0

Error!最后是因为拆分给了你空行"",当你用它检查它时,if(!aLines[i])它会返回true,因为它是空的/空的/什么都没有。您可以在这里检查一下从末尾删除空行,它不会超过数组 4 次。

我还输入了以下显示警报的代码:

    var a="";
    if(!a){
        alert("!a");
    }
于 2012-10-19T19:33:49.190 回答