Prima di tutto, non usare mai un for inciclo per enumerare un array. Mai. Usa il buon vecchio for(var i = 0; i<arr.length; i++).
Il motivo dietro questo è il seguente: ogni oggetto in JavaScript ha un campo speciale chiamato prototype. Tutto ciò che aggiungi a quel campo sarà accessibile su ogni oggetto di quel tipo. Supponiamo che tu voglia che tutte le matrici abbiano una nuova fantastica funzione chiamata filter_0che filtra gli zero.
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]
Questo è un modo standard per estendere oggetti e aggiungere nuovi metodi. Molte biblioteche lo fanno. Tuttavia, diamo un'occhiata a come for infunziona ora:
var listeners = ["a", "b", "c"];
for (o in listeners) {
console.log(o);
}
//prints:
// 0
// 1
// 2
// filter_0
Vedi? Improvvisamente pensa che filter_0 sia un altro indice dell'array. Certo, non è in realtà un indice numerico, ma for inenumera attraverso i campi oggetto, non solo gli indici numerici. Quindi ora stiamo enumerando tutti gli indici numerici e filter_0 . Ma filter_0non è un campo di alcun oggetto array particolare, ogni oggetto array ha questa proprietà ora.
Fortunatamente, tutti gli oggetti hanno un hasOwnPropertymetodo, che controlla se questo campo appartiene davvero all'oggetto stesso o se è semplicemente ereditato dalla catena del prototipo e quindi appartiene a tutti gli oggetti di quel tipo.
for (o in listeners) {
if (listeners.hasOwnProperty(o)) {
console.log(o);
}
}
//prints:
// 0
// 1
// 2
Si noti che sebbene questo codice funzioni come previsto per gli array, non si dovrebbe mai, mai , usare for ine for each inper gli array. Ricorda che for inenumera i campi di un oggetto, non gli indici o i valori dell'array.
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
if (evtListeners.hasOwnProperty(ind))per limitare l'elaborazione solo alle proprietà proprie (non ereditate). Tuttavia, in alcuni casi si desidera veramente scorrere su tutte le proprietà, comprese quelle ereditate. In tal caso, JSLint ti obbliga a racchiudere il corpo del ciclo in un'istruzione if per decidere quali proprietà desideri veramente. Questo funzionerà e renderà felice JSlint:if (evtListeners[ind] !== undefined)