Frage

Ist die „für ... in“ Schleife in Javascript-Schleife durch die Hash-Tabellen / Elemente in der Reihenfolge, wie sie deklariert ist? Gibt es einen Browser, der es nicht um tut?
Das Objekt Ich wünsche wird verwenden erklärt einmal und wird nie geändert werden.

Angenommen, ich habe:

var myObject = { A: "Hello", B: "World" };

Und ich benutze sie weiter in:

for (var item in myObject) alert(item + " : " + myObject[item]);

Kann ich erwarten 'A: "Hallo"' immer kommen vor 'B: "World"'? In den meisten anständigen Browser

War es hilfreich?

Lösung

John Resig Zitiert:

  

Derzeit werden alle gängigen Browser Schleife über die Eigenschaften eines Objekts in der Reihenfolge, in   denen sie definiert sind. Chrome tut dies auch, bis auf ein paar Fälle. [...]   Dieses Verhalten wird ausdrücklich von der ECMAScript-Spezifikation nicht definiert.   In ECMA-262, Abschnitt 12.6.4:

     
    

Die Mechanik, die Eigenschaften aufzuzählen ... ist die Umsetzung abhängig.

  
     

Allerdings Spezifikation ist ganz anders als Umsetzung. Alle modernen Implementierungen   Objekteigenschaften in der Größenordnung von ECMAScript iterieren, in der sie definiert wurden.   Aus diesem Grunde das Chrome-Team dabei um einen Fehler zu sein, als hat und wird es fixiert wird.

Alle Browser respektieren Definition um mit Ausnahme von Chrome und Opera, die tun für jede nicht-numerische Eigenschaftsnamen. In diesen beiden Browsern werden die Eigenschaften in Ordnung vor der ersten nicht-numerischen Eigenschaft gezogen (dies ist hat damit zu tun, wie sie implementieren Arrays). Die Reihenfolge ist für Object.keys auch.

Dieses Beispiel sollte deutlich machen, was passiert:

var obj = {
  "first":"first",
  "2":"2",
  "34":"34",
  "1":"1",
  "second":"second"
};
for (var i in obj) { console.log(i); };
// Order listed:
// "1"
// "2"
// "34"
// "first"
// "second"

Die technischen Details dafür sind weniger wichtig als die Tatsache, dass diese jederzeit ändern kann. Sie nicht auf Dinge verlassen, um diese Art und Weise bleiben.

Kurz gesagt:. ein Array verwenden, wenn zu Ihnen wichtig ist

Andere Tipps

Bumping dies ein Jahr später ...

Es ist 2012 und die gängigen Browser noch unterscheiden:

function lineate(obj){
    var arr = [], i;
    for (i in obj) arr.push([i,obj[i]].join(':'));
    console.log(arr);
}
var obj = { a:1, b:2, c:3, "123":'xyz' };
/* log1 */  lineate(obj);
obj.a = 4;
/* log2 */  lineate(obj);
delete obj.a;
obj.a = 4;
/* log3 */  lineate(obj);

Kern oder Test im aktuellen Browser

Safari 5, Firefox 14

["a:1", "b:2", "c:3", "123:xyz"]
["a:4", "b:2", "c:3", "123:xyz"]
["b:2", "c:3", "123:xyz", "a:4"]

Chrome 21, Opera 12, Knoten 0,6, Firefox 27

["123:xyz", "a:1", "b:2", "c:3"]
["123:xyz", "a:4", "b:2", "c:3"]
["123:xyz", "b:2", "c:3", "a:4"]

IE9

[123:xyz,a:1,b:2,c:3] 
[123:xyz,a:4,b:2,c:3] 
[123:xyz,a:4,b:2,c:3] 

Von der ECMAScript Language Specification , Abschnitt 12.6.4 (auf dem for .. in loop):

  

Die Mechanik, die Eigenschaften von Aufzählen ist die Umsetzung abhängig. Die Reihenfolge der Aufzählung wird durch das Objekt definiert ist.

Und Abschnitt 4.3.3 (Definition von "Objekt"):

  

Es ist eine ungeordnete Sammlung von Eigenschaften, von denen jede enthält einen Grundwert, ein Objekt oder Funktion. Eine Funktion in einer Eigenschaft eines Objekts gespeichert wird ein Verfahren bezeichnet.

Ich denke, das bedeutet, dass Sie verlassen können nicht in einer konsistenten Reihenfolge über JavaScript-Implementierungen aufgezählt auf den Eigenschaften sind. (Es wäre schlechter Stil sowieso sein, sich auf die Implementierung spezifische Details einer Sprache.)

Wenn Sie Ihre Bestellung definiert wollen, müssen Sie etwas implementieren, die es definiert, wie ein Array von Schlüsseln, die Sie sortieren, bevor das Objekt damit erreichbar.

Die Elemente eines Objekts, das für / in zählt auf die Eigenschaften sind, die die DontEnum-Flag nicht haben. Die ECMAScript, auch bekannt als Javascript, Standard sagt ausdrücklich, dass „Ein Objekt ist eine ungeordnete Sammlung von Eigenschaften“ (siehe http://www.mozilla.org/js/language/E262-3.pdf Abschnitt 8.6).

Es wird nicht Standards sein konforme (d safe) alle Javascript-Implementierungen anzunehmen, in der Reihenfolge der Deklaration aufzuzuzählen.

Iterationsreihenfolge ist auch in Bezug auf das Löschen von Eigenschaften verwirrt, aber in diesem Fall mit nur IE.

var obj = {};
obj.a = 'a';
obj.b = 'b';
obj.c = 'c';

// IE allows the value to be deleted...
delete obj.b;

// ...but remembers the old position if it is added back later
obj.b = 'bb';
for (var p in obj) {
    alert(obj[p]); // in IE, will be a, bb, then c;
                   // not a, c, then bb as for FF/Chrome/Opera/Safari
}

Der Wunsch, die Spezifikation für die Änderung der Iteration, um zu beheben scheint unter den Entwicklern ganz ein beliebter Wunsch zu sein, wenn die Diskussion unter http://code.google.com/p/v8/issues/detail?id=164 ist jede Angabe.

in IE6, wird der Auftrag nicht garantiert.

Die Bestellung kann nicht vertraut werden. Sowohl Opera und Chrome Rück die Liste der Eigenschaften ungeordnet.

<script type="text/javascript">
var username = {"14719":"A","648":"B","15185":"C"};

for (var i in username) {
  window.alert(i + ' => ' + username[i]);
}
</script>

Der obige Code zeigt B, A, C in Opera und C, A, B in Chrome.

Das beantwortet nicht die Frage an sich, sondern eine Lösung für das Grundproblem bietet.

Unter der Annahme, dass Sie nicht auf Bestellung zu erhalten verlassen können, warum nicht ein Array von Objekten mit Schlüsseln und Wert als Eigenschaften verwenden?

var myArray = [
    {
        'key'   : 'key1'
        'value' : 0
    },
    {
        'key'   : 'key2',
        'value' : 1
    } // ...
];

Nun ist es an Ihnen, um sicherzustellen, dass die Schlüssel eindeutig sind (unter der Annahme, dass dies für Sie wichtig ist. Wie gut, direkte Adressierung Veränderungen und für (... in ...) gibt nun Indizes als ' Tasten.

> console.log(myArray[0].key);
key1

> for (let index in myArray) {console.log(myArray[index].value);}
0
1
Siehe Pen für (... in ...), um Adressierung von JDQ ( @JDQ ) auf CodePen .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top