Rolf B: Array wird in JS nach JSON-Umwandlung zu Objekt

Beitrag lesen

Hallo Nico,

es tut mir leid, aber: Nein, das ist für JSON kein Array.

Wie die Railroad-Diagramme auf json.org bzw. im ECMA 404 Standard zeigen, ist es in einem Array nicht zulässig, Indizes anzugeben. Es ist auch nicht zulässig, Einträge wegzulassen. Daraus folgt:

Ein Array, das aus einem JSON-String erstellt wird, hat fortlaufende Indizes. Deins nicht, es hat die Indizes 0, 1 und 3.

Es gibt keine Möglichkeit, den Index des ersten Arrayeintrags festzulegen. Das bedeutet, dass JSON.parse diesen Index selbst festlegen muss. In JavaScript ist es tatsächlich erlaubt, in einem Array-Literal Einträge zu überspringen und damit Indexe wegzulassen. [1,2,,3] ist in JavaScript erlaubt. Aber nicht in JSON. Und deswegen beginnen aus JSON erstellte Arrays immer bei Index 0.

PHP und JavaScript haben die Möglichkeit, "sparse arrays" zu erstellen. Das sind Arrays, bei denen nicht alle Indizes belegt sind. Diese Arrayform ist in JSON nicht darstellbar. Eine Datenstruktur, deren Schlüssel nicht fortlaufende Zahlen sind, ist in JSON zwangsweise ein Objekt. Ein JSON-Objekt ist definiert als Liste von Key-Value Paaren. Und der Key ist ein String. Und ein String steht in doppelten Anführungszeichen. So ist es spezifiziert, etwas anderes wird von JSON.parse abgewiesen.

Eine direkte Möglichkeit, dein sparse array aus PHP nach JavaScript zu übertragen, sehe ich nicht. Felix' Vorschlag mit der o2a-Funktion in seinem Fiddle ist ein gangbarer Workaround, er hat aber mutmaßlich einen Fehler drin: Man muss "object" == typeof o[key] abfragen, denke ich, sonst passiert die Rekursion nicht wie gewünscht.

PHP hat diesen "associative" Schalter bei json_decode, den gibt's in JavaScript nicht. Weil es in JavaScript assoziative Arrays so nicht gibt. Es gibt Arrays. Das sind exotische Objekte, in dem Sinne, dass sie eine besondere Verhaltensweise haben, nämlich die length-Eigenschaft. Und sie haben den Methodensatz von Array.prototype, der die Existenz von length voraussetzt. Das kannst Du nur durch Umkopieren sinnvoll adaptieren.

Rolf

--
sumpsi - posui - obstruxi