JavaScript - 谷歌浏览器混乱 Array 生成自 .split()

4

给定以下字符串:

var str = "one,two,three";

如果我按逗号分割字符串,通常会得到一个数组,就像预期的那样:

var arr = str.split(/\s*,\s*/);

问题在于在Google Chrome(Mac版)中,它会将额外的属性附加到数组上。

来自Chrome调试器的输出:

arr: Array
    0: one
    1: two
    2: three
    constructor: function Array()
    index: undefined
    input: undefined
    length: 3

如果我使用for/in循环迭代数组,它会遍历新属性。具体来说,是inputindex属性。使用hasOwnProperty似乎没有帮助。
解决方法是基于数组长度进行for循环。但我仍然想知道为什么Chrome会这样行事。Firefox和Safari没有这个问题。

@KennyTM:为什么不用str.split(',') - Andy E
3
帕特里克显然是这样做的,以从结果数组中删除项目的空格填充。 - Peter Bailey
3
@Peter:确实,我的评论是针对KennyTM的,因为我不确定为什么你要使用正则表达式仅在逗号上进行分割。 - Andy E
所以听起来在数组上使用 for/in 不好。收到。仍然好奇为什么 Chrome 会尝试迭代 inputindex。或者它们为什么存在。 - user113716
5个回答

11
不要使用for...in循环遍历数组!这是 JavaScript 的许多陷阱之一(参见此处) - for...in 循环只用于遍历对象属性。

应该使用普通的 for 循环。

for (var i=0, max = arr.length; i < max; i++) { ... } 


火狐浏览器和Safari浏览器的ECMAScript/Javascript引擎使这些特定属性成为不可枚举的({DontEnum}属性),因此它们不会在for...in循环中被迭代。但是,for...in循环并不打算用于迭代数组索引。


你忘记使用你定义的max变量了 ;) - Gabriele Petrioli
@Gaby:是的,我刚刚意识到了,哈哈。今天真是漫长的一天 :-) - Andy E
你的编辑似乎是关键。Chrome出于某种原因不会将这些属性设置为不可枚举的。我会坚持使用基于长度的循环。 - user113716

3

For..in 用于遍历对象的可枚举属性。对于数组,要遍历它的索引,只需使用标准的for循环。

for ( var i = 0, l = arr.length, i < l; i++ )
{
  // do whatever with arr[i];
}

2

谢谢链接,Pointy。 :) - user113716

1

通常不建议使用for/in循环来迭代数组。首先,迭代的顺序不能保证,此外,您可能会遇到像您目前遇到的问题一样的问题。最好使用传统的for循环。


0
我认为在这里使用正则表达式会得到一个类似于RegExp.exec()执行结果的类似数组对象。
我在Chrome/Win7上无法重现此错误,但我建议使用Array.prototype.slice.call(arr)方法。它被认为是将类似数组转换为真实数组的完美方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接