在对值进行迭代时,为什么typeof(value)返回“0”;“字符串”;当值是一个数字时?JavaScript

在对值进行迭代时,为什么typeof(value)返回“0”;“字符串”;当值是一个数字时?JavaScript,javascript,foreach,typeof,Javascript,Foreach,Typeof,我正在使用Google Chrome进行此测试: 与直觉相反,第一个循环警告“字符串”三次,而第二个循环警告“数字”三次 numarray = [1, 2, 3]; //for-each loop for(num in numarray) alert(typeof(num)); // Standard loop for(i=0; i<numarray.length; i++) alert(typeof(numarray[i])); numarray=[1,2,3];

我正在使用Google Chrome进行此测试:

与直觉相反,第一个循环警告“字符串”三次,而第二个循环警告“数字”三次

numarray = [1, 2, 3];

//for-each loop
for(num in numarray)
    alert(typeof(num));

// Standard loop
for(i=0; i<numarray.length; i++)
    alert(typeof(numarray[i]));
numarray=[1,2,3];
//对于每个循环
用于(Numaray中的数字)
警报(类型(数量));
//标准回路
因为(i=0;i你看到“字符串”的原因在第一个循环中返回的是
num
引用数组索引,而不是该索引处
numarray
的值。请尝试将第一个循环更改为alert
num
,而不是
typeof num
,然后您会看到它会输出0、1和2,它们是标记,而不是数组的值

当您使用
for in
循环时,您正在迭代对象的属性,这与第二个示例中的
for
循环并不完全相同。JavaScript中的数组实际上只是以序号作为属性名称的对象。就
typeof
而言,它们被视为字符串

编辑:

正如Matthew指出的,当使用
for in
循环时,不能保证以任何特定顺序获取数组中的项,部分原因是,不建议以这种方式迭代数组

filip fku询问,鉴于此行为,在
中使用
何时有用。一个例子是属性名称本身有意义,而数组标记的情况并非如此。例如:

var myName = {
  first: 'Jimmy',
  last: 'Cuadra'
};

for (var prop in myName) {
  console.log(prop + ': ' + myName[prop]);
}

// prints:
// first: Jimmy
// last: Cuadra
还值得注意的是,
for in
循环也会遍历对象原型链的属性。因此,这通常是您希望为in
循环构造
的方式:

for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) {
    // do something
  }
}

这将检查属性是否是由对象本身定义的,而不是通过原型链继承的对象。

不能保证数组元素将按顺序访问。请参阅MDC:“迭代数组可能不会按数字顺序访问元素”。这是..in通常不建议用于数组的主要原因。很有趣!不同于人们对C#/Java的期望..但是当您得到的只是索引而不是数组值本身时,这怎么会比显式编写循环的标准更好呢?也就是说,当您得到的都是索引时,为什么还要使用这个呢是吗?(我想我可以看到关联数组的用法)。至于第二部分,有没有办法获得一个对象的属性名称数组?@Mark-你可以使用
for in
循环遍历属性,并将每个属性推送到一个数组中。我认为没有insta magic方法可以做到这一点。它还可以在IE中提醒“string”。可能存在重复的属性