Javascript for..in Schleifen über Argumente ie.for (arg in arguments) funktioniert nicht in IE8, aber es funktioniert in Chrome 8

8

Ich habe mich dieser seltsamen Situation gegenübergestellt, wo foreach wie das Konstrukt von Javascript im IE nicht funktioniert, aber es funktioniert in FF. Nun, nicht alle for..in nur diese spezielle Funktion funktioniert nicht. Ich werde den Code posten. Getestet in IE8. Getestet auch mit XHTML DTD.

%Vor%

Update Ich habe eine falsche Frage gepostet, dass es in FireFox funktioniert, aber nicht in IE8, was falsch war. Es funktioniert auch nicht in FireFox. Eigentlich habe ich diesen Code von post JavaScript gleichbedeutend mit printf / string.format .

    
samarjit samanta 28.01.2011, 02:17
quelle

5 Antworten

23

Zu allererst ist das in einer Funktion verfügbare Objekt arguments kein Array, es ist jedoch "Array-artig" genug, so dass eine inkrementelle for-Schleife ( for (var i = 0, len = arguments.length; i < len; i++) { ... } ) vorzuziehen ist - nicht nur, weil es schneller läuft , aber auch, weil es andere Fallstricke vermeidet - eine davon ist genau das, in was Sie fallen.

Um die Frage nach zu beantworten, warum die zweite Schleife nicht funktioniert, ist es wichtig, genau zu wissen, was for ... in loop: iteriert durch alle aufzählbar Eigenschaften in einem Objekt gefunden. Jetzt habe ich zwei Wörter in dieser Aussage hervorgehoben, weil ich diese zwei Wörter gezielt verwendet habe, um auf einige Nuancen hinzuweisen, die, obwohl sie subtil wirken, das Verhalten Ihres Codes drastisch beeinflussen können, wenn Sie nicht erkennen, was vor sich geht .

Zuerst konzentrieren wir uns auf all - damit meine ich nicht nur die Eigenschaften des Objekts selbst, sondern auch potentielle Eigenschaften, die das Objekt von seinem Prototyp oder seinem Prototyp geerbt hat auf. Aus diesem Grund wird es sehr oft empfohlen, dass Sie jede for ... in-Schleife "schützen", indem Sie sie sofort zusätzlich mit der Bedingung if (obj.hasOwnProperty(p)) qualifizieren (vorausgesetzt, Ihre Schleife wurde als for (var p in obj) geschrieben).

Aber das ist nicht, worauf Sie hier stoßen. Konzentrieren wir uns dafür auf das zweite Wort aufzählbar . Alle Eigenschaften von Objekten in JavaScript sind entweder aufzählbar oder nicht aufzählbar, was sich ziemlich direkt darauf bezieht, ob die Eigenschaft in einer for ... in-Schleife angezeigt wird oder nicht. In Browsern wie Firefox und IE, wie sich herausstellt, sind die numerischen Eigenschaften des arguments -Objekts nicht aufzählbar (noch ist es length , so wie es war), und genau deshalb bist du es nicht alles durchspielen!

Aber am Ende, um alles zu durchlaufen, was ein Array oder ein Array-ähnliches ist, verwenden Sie besser eine inkrementelle Schleife (wie M. Kolodny auch sagte), und vermeide diese Spielereien (ganz zu schweigen vom Potential browserübergreifende Inkonsistenzen - Ich habe festgestellt, dass in Chrome 10 die numerischen Eigenschaften von arguments objekte aufzählbar sind!)

    
Ken Franqueiro 28.01.2011, 04:07
quelle
2

Verwenden Sie dies als Formatfunktion:

%Vor%

Das sollte jetzt funktionieren:

%Vor%

DEMO

Getestet und funktioniert in IE

    
Moshe K. 28.01.2011 02:49
quelle
0

Aus meinem Test, mit Firefox 3.6.13 und IE 8 sehe ich keinen Unterschied im Verhalten, beide gehen nicht in die zweite Schleife.

Ein Unterschied zwischen mycars und arguments ist, dass mycars ein Array ist, während Argumente ein Objekt sind.

Um das zu demonstrieren:

%Vor%

Allerdings kann ich mit etwas Testcode sehen, dass "for in" für Array und Object

funktioniert %Vor%

Ich bin mir also nicht sicher, wie sich das Argument Objects von einem selbst konstruierten Objekt mit dem geschweiften Klammernliteral unterscheidet. Ich denke, es ist verwirrend, weil in diesem Test für sowohl das Array als auch das Objekt funktioniert. Während das "for in" nicht mit Argumenten funktioniert.

Auch hier habe ich in allen Tests keinen Unterschied zwischen FF 3.6 und IE 8 festgestellt.

UPDATE : Wie ich dank Ken-Kommentaren herausgefunden habe, sind die Eigenschaften von Argumenten als nicht aufzählbar definiert, während beim Definieren eines Objekts literale Eigenschaften implizit als aufzählbar definiert sind.

    
stivlo 28.01.2011 03:30
quelle
0

Einige Browser unterstützen for..in wie Chrome und Firefox 4, um Argumente zu iterieren, aber andere Browser sehen ihre Parameter nicht, während sie so iterieren. Ich wette, dass in diesen Browsern, wenn Sie JSON.stringify (Argumente) getan hätten, das Ergebnis ein leeres Objekt wäre. Bei der Spezifikation von JavaScript 1.1 und weiteren Argumenten gibt es einen length-Parameter, so dass Sie diese mit for (var i = 0; i < arguments.length; i++) und while(i < arguments.length) loops iterieren können.

Persönlich, sobald ich mit for..in für Argument Iteration verbrannt wurde, schrieb ich eine einfache Funktion für Argument-Objekt-Iteration, die nicht von der Länge abhängt, weil die Argumente immer in der Reihenfolge von IDs gekennzeichnet sind.

%Vor%

Ich benutze es seither, wenn ich Argumente wiederhole und es scheitert mich nicht. Mehr darüber in meinem Blogbeitrag Ссылка

    
stamat 20.12.2013 00:41
quelle
-2

Nun, es sollte funktionieren, wenn nicht, dann ist die Antwort so einfach wie "es ist noch ein weiterer Fehler im IE".

Aber die eigentliche Frage ist, warum Sie for ... in verwenden, um über Arrays oder arrayähnliche Objekte (wie arguments ) zu iterieren - verwenden Sie stattdessen einfach eine einfache for -Schleife, die in allen Hauptfunktionen funktioniert Browser:

%Vor%     
casablanca 28.01.2011 02:25
quelle