Zunächst einmal, nie eine Verwendung for in
Schleife ein Array aufzählen über. Noch nie. Verwenden Sie gute alte for(var i = 0; i<arr.length; i++)
.
Der Grund dafür ist folgender: Jedes Objekt in JavaScript hat ein spezielles Feld namens prototype
. Alles, was Sie diesem Feld hinzufügen, ist für jedes Objekt dieses Typs zugänglich. Angenommen, Sie möchten, dass alle Arrays eine coole neue Funktion haben filter_0
, die Nullen herausfiltert.
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]
Dies ist eine Standardmethode zum Erweitern von Objekten und Hinzufügen neuer Methoden. Viele Bibliotheken tun dies. Schauen wir uns jedoch an, wie es for in
jetzt funktioniert:
var listeners = ["a", "b", "c"];
for (o in listeners) {
console.log(o);
}
//prints:
// 0
// 1
// 2
// filter_0
Siehst du? Es denkt plötzlich, dass filter_0 ein weiterer Array-Index ist. Natürlich ist es nicht wirklich ein numerischer Index, sondern for in
zählt durch Objektfelder auf, nicht nur durch numerische Indizes. Also zählen wir jetzt jeden numerischen Index auf und filter_0
. Ist filter_0
aber kein Feld eines bestimmten Array-Objekts, hat jedes Array-Objekt jetzt diese Eigenschaft.
Glücklicherweise haben alle Objekte eine hasOwnProperty
Methode, die prüft, ob dieses Feld wirklich zum Objekt selbst gehört oder ob es einfach von der Prototypenkette geerbt wird und somit zu allen Objekten dieses Typs gehört.
for (o in listeners) {
if (listeners.hasOwnProperty(o)) {
console.log(o);
}
}
//prints:
// 0
// 1
// 2
Beachten Sie, dass dieser Code, obwohl er für Arrays wie erwartet funktioniert, niemals, niemals funktionieren sollte , Verwendung for in
und for each in
für Arrays. Denken Sie daran, dass for in
die Felder eines Objekts aufgelistet werden, nicht Array-Indizes oder -Werte.
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))
um die Verarbeitung nur auf eigene (nicht vererbte) Eigenschaften zu beschränken. In einigen Fällen möchten Sie jedoch wirklich alle Eigenschaften durchlaufen, einschließlich der geerbten. In diesem Fall zwingt JSLint Sie, den Schleifenkörper in eine if-Anweisung zu packen, um zu entscheiden, welche Eigenschaften Sie wirklich möchten. Dies wird funktionieren und JSlint glücklich machen:if (evtListeners[ind] !== undefined)