Warum gibt JSON.parse (['1234']) 1234 zurück?

75

Ich habe Probleme, das Verhalten von zu verstehen JSON.parse. JSON.parsesollte nur für Strings funktionieren. Es scheint jedoch für ein Array zu funktionieren, das nur eine Zeichenfolge enthält (auch in einfachen Anführungszeichen), wenn die Zeichenfolge nur Zahlen enthält.

JSON.parse(['1234']) // => 1234
JSON.parse(['1234as']) // => throws error
JSON.parse(['123', '123']) // => throws error
Akshendra Pratap
quelle
2
Ich weiß, dass keiner von ihnen kein gültiger JSON ist. Aber dann sollte JSON.parse einen Fehler auslösen, wie ich es im ersten Fall erwartet hatte, aber das ist es nicht.
Akshendra Pratap
57
BITTE beziehen Sie sich nicht auf w3schools, um JSON zu verstehen. Ich habe es gerade überprüft und es ist in vielerlei Hinsicht so falsch.
Dancrumb
2
Ich denke auch, was Solomonoff meinte, war "Dies ist JavaScript. Sie sollten erwarten, dass es der ECMAScript-Spezifikation entspricht, die genau erklärt, was passiert, wenn Sie einen Nicht-String an eine Funktion übergeben, die einen String erwartet"
Dancrumb
1
Zu Ihrer Information: "Auch in einfachen Anführungszeichen" hat hier keine Relevanz. Einfache und doppelte Anführungszeichen um eine JavaScript- Zeichenfolge haben keinen Einfluss auf ihre Gültigkeit als JSON.
Meagar
1
@TravisJ Sie sind verwirrt darüber, welcher Teil JavaScript und welcher Teil JSON ist. Die Anführungszeichen um die JavaScript- Zeichenfolge spielen in Ihrem Beispiel keine Rolle, und Sie haben für beide Beispiele einfache Anführungszeichen ausgewählt, wobei der Punkt vollständig verfehlt wurde. Die Anführungszeichen in der JavaScript-Zeichenfolge, die Teil des codierten JSON sind, sind absolut wichtig, und ich habe nie angegeben, dass dies nicht der Fall ist. Die Anführungszeichen zum Erstellen eines Zeichenfolgenliteral in JavaScript haben keinen Einfluss darauf, ob die Zeichen in dieser Zeichenfolge gültiges JSON sind. Es gibt keinen Unterschied zwischen Parsen '"foo"'und "\"foo\"", sie sind buchstäblich identische Zeichenfolgen.
Meagar

Antworten:

179

Erwartet, wie Sie bereits betont haben, JSON.parse()eine Zeichenfolge und kein Array. Wenn jedoch ein Array oder ein anderer Wert ohne Zeichenfolge angegeben wird, erzwingt die Methode automatisch eine Zeichenfolge und fährt fort, anstatt sofort zu werfen. Aus der Spezifikation :

  1. Sei JText ToString (Text).
  2. ...

Die Zeichenfolgendarstellung eines Arrays besteht aus seinen durch Kommas getrennten Werten. Damit

  • String(['1234'])kehrt zurück '1234',
  • String(['1234as'])kehrt zurück '1234as'und
  • String(['123', '123'])kehrt zurück '123,123'.

Beachten Sie, dass Zeichenfolgenwerte nicht erneut in Anführungszeichen gesetzt werden. Dies bedeutet, dass ['1234']und [1234]beide in dieselbe Zeichenfolge konvertieren '1234'.

Was Sie also wirklich tun, ist:

JSON.parse('1234')
JSON.parse('1234as')
JSON.parse('123,123')

1234asund 123,123sind nicht gültig JSON, und so JSON.parse()wirft in beiden Fällen. (Ersteres ist zunächst keine legale JavaScript-Syntax, und letzteres enthält einen Kommaoperator, der nicht dazu gehört.)

1234Auf der anderen Seite ist ein Zahlenliteral und daher ein gültiger JSON, der sich selbst darstellt. Und deshalb JSON.parse('1234')(und im weiteren Sinne JSON.parse(['1234'])) wird der numerische Wert 1234 zurückgegeben.

BoltClock
quelle
12
"..ist ein Zahlenliteral und daher gültiges JSON .." - Ein einzelnes Zahlenliteral ist kein gültiges JSON, aber JSON.parsenicht sehr streng (insbesondere analysiert es JSON-Objekte und einzelne Werte) . Sehen Sie hier für weitere Informationen.
BlueRaja - Danny Pflughoeft
18
@ BlueRaja-DannyPflughoeft Ich bin deinem Link gefolgt. Es stimmt nicht mit Ihrer Schlussfolgerung überein. Wenn Sie mit "gültiger JSON" "einen gültigen JSON-Text" meinen, war ein einzelnes Zahlenliteral früher ungültig, ist aber jetzt gültig. Darüber hinaus hat "gültiger JSON" andere gültige Interpretationen als "ein gültiger JSON-Text", und bei einigen anderen Interpretationen war immer ein einzelnes Zahlenliteral gültig.
11
Man kann dies auf die nächste Stufe bringen mit JSON.parse(['[123', '123]']): P
Siguza
5
@ BlueRaja-DannyPflughoeft RFC 7159 und ECMA-404 haben die JSON-Spezifikation überarbeitet, damit der Wert der obersten Ebene eine Zahl oder Zeichenfolge sein kann, nicht nur ein Objekt oder ein Array. JSON.parse()steht im Einklang mit dieser Änderung.
Barmar
6
@ BlueRaja-DannyPflughoeft: Es gibt leider mehrere Versionen von JSON. Es gibt die Originalversion von Doug Crockford auf JSON.org . Es gibt jedoch auch zwei internationale Standards für JSON, nämlich ECMA-404 (das die Spezifikation in Abschnitt 15.12.1 der ECMA-262 5.1 Edition ersetzt ) und RFC 7159 (das RFC 4627 ersetzt ). Es gibt auch die…
Jörg W Mittag
22

Wenn JSON.parse keine Zeichenfolge erhält, wird zuerst die Eingabe in eine Zeichenfolge konvertiert.

["1234"].toString() // "1234"
["1234as"].toString() // "1324as"
["123","123"].toString() // "123,123"

Von all diesen Ausgaben weiß es nur, wie man "1234" analysiert.

Naortor
quelle
4

Zwei Dinge, die hier zu beachten sind:

1) JSON.parsekonvertiert das Argument in eine Zeichenfolge (siehe den ersten Schritt des Algorithmus in der Spezifikation). Ihre Eingabe führt zu folgenden Ergebnissen:

['1234']       // String 1234
['1234as']     // String 1234as
['123', '123'] // String 123,123

2) Die Spezifikationen auf json.org besagen, dass:

[...] Ein Wert kann eine Zeichenfolge in doppelten Anführungszeichen oder eine Zahl oder wahr oder falsch oder null oder ein Objekt oder ein Array sein. Diese Strukturen können verschachtelt werden.

Also haben wir:

JSON.parse(['1234'])
// Becomes JSON.parse("1234")
// 1234 could be parsed as a number
// Result is Number 1234 

JSON.parse(['1234as'])
// Becomes JSON.parse("1234as")
// 1234as cannot be parsed as a number/true/false/null
// 1234as cannot be parsed as a string/object/array either
// Throws error (complains about the "a")

JSON.parse(['123', '123'])
// Becomes JSON.parse("123,123")
// 123 could be parsed as a number but then the comma is unexpected
// Throws error (complains about the ",")
Salman A.
quelle