BlogKontaktTagcloud

"Defekte" for-in-Schleife in JavaScript

"Hunderttausend Höllenhunde" würde Kapitän Haddock wohl zu JavaScript sagen. Ganz werde ich diese Programmiersprache wohl nie verstehen. Man kann mit ihr wunderbare Dinge basteln und ebenso wunderbare Fehler. So geschehen mit meiner neuen Suchmaschine "Loogel".

Ein for-in-Loop über ein assoziatives Array verweigerte im IE seinen Dienst, während das gleiche Konstrukt in einem anständigen Browser ohne Probleme lief. Im Internet gibt es allerlei Erklärungen zu nicht funktionierenden for-in-Schleifen, die hatten aber alle genau gar nichts mit meinem Problem zu tun. Und um es gleich vorweg zu nehmen, der Internet Explorer kann in diesem Fall nicht allzu viel dafür.

Im nachfolgenden das stark vereinfachte Beispiel. Im Firefox läuft das ganze ohne Probleme während im Internet Explorer die vielsagende Meldung "Das Objekt unterstützt diese Eigenschaft oder Methode nicht." erscheint.

<html><head><title>Test</title>
<script type="text/javascript">
function OnLoad(){
var Ausgabe = "";
var obj = new Object();
obj[324] = "adff";
for (Eigenschaft in obj)
Ausgabe = Ausgabe + Eigenschaft+ ": " + obj[Eigenschaft] + "<br>";
document.write("<h1>Eigenschaften des Objekts <i>document<\/i><\/h1>");
document.write(Ausgabe);
}
</script>

</head>
<body onload="OnLoad()">
<div id="Eigenschaft"></div>
</body>
</html>
Das Problem beginnt damit, dass der DIV-Block mit der id "Eigenschaft" automatisch als Variable im Skope zur Verfügung steht. Mit alert(Eigenschaft); vor dem for-Loop erkennt man das hier das Objekt des Div-Blocks (HTMLDivElement) zugewiesen ist. Der Firefox überschreibt nun dieses Objekt einfach, der Internet Explorer hingegen gibt einen Fehler aus. Richtig wäre das ganze mit einem var vor der Eigenschaft.
   for (var Eigenschaft in obj)
Ausgabe = Ausgabe + Eigenschaft+ ": " + obj[Eigenschaft] + "<br>";
Der Div-Block wird danach nicht mehr automatisch der Variablen zugeordnet. alert(Eigenschaft); vor dem for-Loop gibt nun "undefined" zurück. (Was wiederum aus meiner Sicht ein wenig magisch ist.)

Der Sünder ist in diesem Fall jedoch nicht der Internet Explorer. Seine Fehlermeldung ist zwar wenig aussagekräftig, aber durchaus korrekt. Nach ECMA-Standard gibt es zwei for-in-Loops, einen mit var und einen ohne. Bei denjenigen ohne var muss vor dem in eine LeftHandSideExpression stehen, was zum Beispiel ein Feldaufruf, ein Arrayzugriff oder ein Funktionsaufruf sein kann, jedoch kein Objekt wie in meinem Beispiel.
Ähnliche Beiträge:
Parallel Request mit AJAX und PHP
Assoziative Array nach Value sortieren
Synchroner Aufruf mit XMLHttpRequest in Firefox
Webtuesday: PHP wins!
Webtuesday: PHP vs. Javascript: which sucks more?
Comments (4)  Permalink

comments

Heiko @ 29.12.2006 22:04 CET
Prima Argument für die Diskussion "PHP vs. Javascript: which sucks more" :)
leo @ 30.12.2006 11:11 CET
Ja, wirklich! Ich mag JavaScript einfach nicht, irgendwie ist mir da alles zu wenig klar.

Das grösste Problem ist aber wohl das es mehrere Interpreter, die von verschiedenen Gruppen implementiert werden, gibt die trotz Standard nicht wirklich einheitlich sind.

Mal sehen wie Sun das mit OpenSource Java hinbringen wird...
Struppi @ 31.05.2007 10:52 CET
Mal abgesehen von dem etwas schlimmen Beispiel (onload im Body-Tag, document.write() zur Ausgabe) ist es natürlich ein Fehler des IEs. In meinem FF gibt es keine Eigenschaft window.Eigenschaft und folgerichtig erhalte ich den Fehler:
Fehler: Eigenschaft is not defined
Wenn ich ein alert(Eigenschaft) vor der Schleife einbaue, es sei denn ich versetzte den Browser in den Quirksmode, wovon aber immer abzuraten ist.

Es ist übertriebende Höflichkeit des IE gegenüber schludrigen Programmieren, dass er alles was möglich ist auch ohne die Funktionen Verfügbar macht.

Globale Variabeln (also in einer Funktion ohne var deklarierte) sind sowieso sehr schlechter Stil und sollten vermieden werden.
koens @ 07.08.2008 16:20 CET
Thanks for your help. Had the same prob...

add a comment

The Trackback URL to this comment is:
http://leo.freeflux.net/blog/plugin=trackback(1835).xml

Keine (weiteren) neuen Kommentare erlaubt.