Не используйте for ..in с массивами, где важен порядок !!
Использование for..in с массивами имеет следующие опасности:
Будут возвращены все перечисляемые свойства массива , в том числе свойства Array.prototype и самого массива, поэтому либо вы должны быть абсолютно уверены, что таких расширений не было, либо вы должны сделать hasOwnProperty и проверки числовых индексов
Порядок, в котором возвращаются ключи, не гарантируется и может быть легко нарушен - IE возвращает их в порядке их добавления, поэтому, если они добавляются не по порядку (например, с использованием уменьшающего цикла while, который является довольно часто) они будут возвращены в обратном порядке
Попробуйте следующее в Firefox и IE:
var a = [0,1,2,3];
var b = [];
var i = a.length;
while (i--) {
b[i] = a[i];
}
var s = [];
for (var p in b) {
s.push(b[p]);
}
alert(b + '\n' + s);
// Firefox: 0,1,2,3
// 0,1,2,3
// IE: 0,1,2,3
// 3,2,1,0
Там, где важен порядок, только используют циклы, где вы явно обращаетесь к ключам в нужном вам порядке. Это также относится к объектам, поскольку в javascript порядок, в котором свойства возвращаются с использованием for..in для всех объектов, зависит от реализации и различается в разных браузерах (отмечая, что в javascript все является объектом).
For..in нормально использовать с массивами, где вышеуказанные проблемы либо не важны, либо решаются. Это удобный инструмент для разреженных массивов и доступа к нечисловым перечислимым свойствам.
Общая функция транспонирования:
function rows2cols(a) {
var r = [];
var t;
for (var i=0, iLen=a.length; i<iLen; i++) {
t = a[i];
for (var j=0, jLen=t.length; j<jLen; j++) {
if (!r[j]) {
r[j] = [];
}
r[j][i] = t[j];
}
}
return r;
}
Он может быть сокращен и оптимизирован, но вышеприведенная функция является достаточно эффективной и легко поддерживаемой.