Прежде всего, никогда использует цикл for in
для перечисления по массиву. Никогда. Используйте старый добрый for(var i = 0; i<arr.length; i++)
.
Причина этого заключается в следующем: каждый объект в JavaScript имеет специальное поле с именем prototype
. Все, что вы добавите в это поле, будет доступно для каждого объекта этого типа. Предположим, вы хотите, чтобы у всех массивов была новая классная функция с именем filter_0
, которая будет фильтровать нули.
Array.prototype.filter_0 = function() {
var res = [];
for (var i = 0; i < this.length; i++) {
if (this[i] != 0) {
res.push(this[i]);
}
}
return res;
};
console.log([0, 5, 0, 3, 0, 1, 0].filter_0());
//prints [5,3,1]
Это стандартный способ расширения объектов и добавления новых методов. Многие библиотеки делают это.
Однако давайте посмотрим, как теперь работает for in
:
var listeners = ["a", "b", "c"];
for (o in listeners) {
console.log(o);
}
//prints:
// 0
// 1
// 2
// filter_0
Вы видите? Он вдруг думает, что filter_0 - это еще один индекс массива. Конечно, это на самом деле не числовой индекс, но for in
перечисляет через поля объекта, а не только числовые индексы. Итак, мы сейчас перечисляем все числовые индексы и filter_0
. Но filter_0
не является полем какого-либо конкретного объекта массива, каждый объект массива теперь обладает этим свойством.
К счастью, у всех объектов есть метод hasOwnProperty
, который проверяет, действительно ли это поле принадлежит самому объекту или оно просто унаследовано из цепочки прототипов и, следовательно, принадлежит всем объектам этого типа.
for (o in listeners) {
if (listeners.hasOwnProperty(o)) {
console.log(o);
}
}
//prints:
// 0
// 1
// 2
Обратите внимание, что хотя этот код работает как положено для массивов, вы никогда не должны никогда использовать for in
и for each in
для массивов. Помните, что for in
перечисляет поля объекта, а не индексы или значения массива.
var listeners = ["a", "b", "c"];
listeners.happy = "Happy debugging";
for (o in listeners) {
if (listeners.hasOwnProperty(o)) {
console.log(o);
}
}
//prints:
// 0
// 1
// 2
// happy