混淆了 for...in 语句 JS 输出的结果

Confused with a result of a for...in statement JS output

我只是在测试 Java 脚本...在(只是一个新手 :P :D )。

我尝试了以下代码:

var arr=[];
arr['n1']='name1';
arr['n2']='name2';
arr['n3']='name3';
arr['n4']='name4';

var i,j;

for(i in arr)
{
    for(j in i)
        document.writeln(j+"-");
}

输出为:

0- 1- 0- 1- 0- 1- 0- 1-

我想知道为什么我会得到这样的输出。

for...in 循环如果尝试输出 'i' 而不是 'j' 我正在获取索引名称。

当我检查 typeof 'j' 时,我得到它作为字符串。

请帮助我理解输出。

这就是您的代码的工作方式,

var arr=[];
arr['n1']='name1';
arr['n2']='name2';
arr['n3']='name3';
arr['n4']='name4';

var i,j;

for(i in arr) {
 // i will be the keys, n1,n2,n3,n4
 // And those keys are strings.
 // You are traversing over the enumerable properties of strings "n1","n2"..
 // So enumerable property of "n1" will be 0 and 1. 
 // So it is getting printed in the internal loop
 for(j in i) {
  document.writeln(j+"-");
 }
}

最好不要对数组使用for in 循环,因为它会遍历整个原型链中的所有可枚举属性。请改用简单的 for 循环。或者只使用 .hasOwnProperty() 来确保可枚举的 属性 属于 immediate/own 原型链。

似乎每个人都想回答您没有提出的问题。所以这里是你问题的答案。

当你在数组上使用 for..in 时,你只会得到数组键。在您的情况下 "n1"、"n2" 等。

当您在字符串上使用 for..in 时,您将获得该字符串的索引。在您的情况下,您有一堆两个字符串,因此每个字符串都会得到 0 和 1。

要查看发生了什么,试试这个:

for (i in 'test') {
    console.log(i)
}

输出: 0 1 2 3

因为是4个字符的字符串。

但所有评论都是正确的。不要这样做。阅读他们提供的一些链接。

Javascript 没有关联数组。
您不能以这种方式填充常规数组:arr['n1']='name1';

If you use a named index, JavaScript will redefine the array to a standard object. After that, all array methods and properties will produce incorrect results.

var arr=[];
arr['n1']='name1';
arr['n2']='name2';
arr['n3']='name3';
arr['n4']='name4';
var x = arr.length;         // arr.length will return 0
var y = arr[0];             // arr[0] will return undefined

至于 for-in 循环 - 这个循环有一个非常特殊的用途:它 枚举任何对象的命名属性。

for(i in arr)
{
    for(j in i)
        document.writeln(j+"-");
}

'parent'循环将迭代命名属性,例如n1n2等。 嵌套循环期望第二个操作数是一个对象:i 应该是这个表达式 (j in i) 中的一个对象。但实际值是一个字符串(n1n2n2)。因此,Javascript 将在幕后的每次迭代中为每个字符串创建 Primitive Wrapper Object

...
for(j in i) // actually would be (for j in new Object('n1'))
   // console.log(new Object('n1'));
   // String {0: "n", 1: "1", length: 2, [[PrimitiveValue]]: "n1"}
   document.writeln(j+"-");
...

如您所见,原始包装器对象的每个字符串都有两个 "numbered" 属性。这就是它给你输出的方式:

0- 1- 0- 1- 0- 1- 0- 1-