Hallo zusammen, diese Woche möchte ich über eine kleine Stolperfalle von Javascript schreiben – Die ein- oder anderen kennen dieses „merkwürdige“ Verhalten vielleicht aus eigener Erfahrung 😉

Das Problem kann bei der Nutzung von Frameworks (wie z.B. Prototype) auftreten oder sobald man auf eigene Faust die Standard Klassen (String, Array, …) erweitert.

Worüber reden wir hier?

Werden die Standard Klassen durch Frameworks oder den eigenen Code erweitert, kann es beim iterieren über Arrays oder Objekte mit Hilfe einer „for..in“ Schleife passieren, das wir nicht nur über die eigentlichen Inhalte, sondern auch über die geerbten Methoden iterieren:

// Wir gehen davon aus, dass das Prototype Framework eingebunden ist.
var my_array = [],
    key;

for (key in my_array) {
    console.log(key);
}


Führen wir diesen Code aus, bekommen wir ca. 38 Methoden gelistet – Hier ein Ausschnitt:

each
eachSlice
all
any
collect
detect
findAll
select
grep
...

Dieses „Problem“ kann auch bei anderen Situationen auftreten, zum Beispiel wenn wir durch ein leeres Hash-Objekt iterieren (Dieser Code bezieht sich ebenfalls auf Prototype):

var my_hash = $H(); // Oder: "var my_hash = new Hash;"

for (key in my_hash) {
    console.log(key);
}

Wie können wir dieses Verhalten umgehen?

Um unseren Code sauber und sicher zu halten, können wir einfach die native Methode hasOwnProperty nutzen – Diese prüft, ob es sich beim übergebenen String um ein tatsächliche Eigenschaft der Objekt-Instanz oder dessen Prototypen (Parent-Klasse) handelt. Das ganze sieht dann folgendermaßen aus:

var my_array = [],
    key;

for (key in my_array) {
    if (my_array.hasOwnProperty(key)) {
        console.log(key);
    }
}

Diverse IDEs (wie z.B. PhpStorm) und Skripe zur Syntax-Validierung (wie z.B. JSLint) machen auf for..in Schleifen, denen der hasOwnProperty-Check fehlt, aufmerksam.

Wenn das Framework eurer Wahl eine eigene Methode für Iterationen anbietet (z.B. „each„), kann man diese natürlich benutzen… Aber es ist nicht gesagt, dass das Problem damit aus der Welt ist. Außerdem werdet ihr womöglich eine anonyme Funktion übergeben müssen und das kostet performance!

// Beispiel einer Schleife mit Hilfe von "each()" (Prototype).
var my_array = [];

my_arary.each(function(item, key) {
    // Code...
});

Geht also lieber auf Nummer sicher und vertraut nicht blind auf Frameworks oder sonstige Helferlein. Es ist niemals verkehrt die Hintergründe zu kennen:

‚Rausfinden wieso ein Fehler passiert‘ statt nur ‚Rausfinden wie man einen Fehler beseitigt‘!

Mit diesen Worten möchte ich mich für diese Woche verabschieden – Ich werde versuchen in den kommenden Wochen ebenfalls zu posten, kann es aber leider nicht versprechen. Weihnachten und Neujahr werden ggf. etwas mehr Planung und Zeit beanspruchen als gedacht 😉

In diesem Sinne – Happy Coding!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.