Причина, по которой вы видите «строку», возвращенную в первом цикле, заключается в том, что num
ссылается на индекс массива , а не на значение numarray
в этом индексе. Попробуйте изменить свой первый цикл на предупреждение num
вместо typeof num
, и вы увидите, что он выплевывает 0, 1 и 2, которые являются индикаторами, а не значениями вашего массива.
Когда вы используете цикл for in
, вы перебираете свойства объекта, что не совсем эквивалентно циклу for
во втором примере. Массивы в JavaScript - это на самом деле просто объекты с последовательными числами в качестве имен свойств. С точки зрения typeof
они рассматриваются как строки.
Edit:
Как указывает Мэтью, вы не гарантированно получите элементы в массиве в каком-то определенном порядке при использовании цикла for in
, и частично по этой причине не рекомендуется перебирать массивы таким образом.
filip-fku спрашивает, когда было бы полезно использовать for in
, учитывая это поведение. Один из примеров - это когда сами имена свойств имеют значение, что на самом деле не так для указателей массива. Например:
var myName = {
first: 'Jimmy',
last: 'Cuadra'
};
for (var prop in myName) {
console.log(prop + ': ' + myName[prop]);
}
// prints:
// first: Jimmy
// last: Cuadra
Стоит также отметить, что циклы for in
также будут проходить через свойства цепочки прототипов объекта. По этой причине обычно вы хотите построить цикл for in
:
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
// do something
}
}
При этом проверяется, определено ли свойство самим объектом, а не объектом, от которого оно наследуется в цепочке прототипов.