Warum wird 0.-5 mit -5 bewertet?

81

Angenommen, ich schreibe 0.5wie 0.-5auf unerwartete Weise, aber es kann immer noch ausgeführt werden. Was ist 0.in 0.-5tun , so dass es nach wie vor zu laufen und auswertet , kann sie -5?

Ich habe auch versucht, alert(0.-5+1)welche Drucke -4, ignoriert JavaScript 0.in 0.-5?

ocomfd
quelle
55
0.ist wie 0.0. Oder einfach nur 0.
Ry-
61
Was lässt Sie denken, dass dies 0.-5ein "unerwarteter Weg" ist?
Nico Haase
15
@NicoHaase: Ich bin mir ziemlich sicher, dass das OP "unerwartete Art" verwendet hat, um zu bedeuten "Ich habe nicht beabsichtigt / erwartet, das zu schreiben, aber irgendwie habe ich es getan".
Filip Milovanović
15
Dies funktioniert auch in vielen anderen Sprachen (z. B. Python). Ich persönlich mag es überhaupt nicht. Ich wäre lieber 0.-5ein Syntaxfehler und würde keine Float-Literale mit einer nachgestellten Periode zulassen, sondern die Leute zwingen, .0am Ende zu schreiben .
Giacomo Alzetta
9
Es ist besonders schlimm, weil das Zulassen, dass Zahlen enden, .Sie daran hindert, etwas zu schreiben wie 123.toString(16)(Ein üblicher Trick ist die Verwendung 123..toString(16), was wirklich so ist (123.).toString(16))
12Me21

Antworten:

187

Nachgestellte Ziffern nach a .sind optional:

console.log(0. === 0); // true

So

0.-5

bewertet zu

0 - 5

das ist nur -5. Ähnlich,

0.-5+1

ist

0 - 5 + 1

welches ist

-5 + 1

oder -4.

Bestimmte Leistung
quelle
14
Führende Ziffern sind ebenfalls optional, daher ist .0-5 ebenfalls gültig
icenac
48

0.-5konnte erfolgreich als 0.[1] analysiert werden , -und 5. Unten finden Sie den abstrakten Syntaxbaum für den vom AST-Explorer generierten Ausdruck:

Vom AST-Explorer generierter Analysebaum

Dies ist (auf unerwartete Weise) gültiges JavaScript und wird ausgewertet -5.


[1] Gemäß der Grammatik für numerische Literale sind die Dezimalstellen und Exponententeile optional:

NumericLiteral ::
  DecimalLiteral
  [...]

DecimalLiteral ::
  DecimalIntegerLiteral. DecimalDigits opt ExponentPart opt

Salman A.
quelle
Wie haben Sie den AST extrahiert?
Κωλζαρ
7
Gehen Sie zu astexplorer.net , wählen Sie eine Sprache und einen Parser aus, fügen Sie den Code ein, wählen Sie die JSON-Ausgabe (oder machen Sie einfach einen Screenshot).
Salman A
39

In JS können Sie eine Zahl mit optionalem Dezimalpunkt ausdrücken.

x = 5.;    //5
x = 5. + 6.   //11

Und ab dem Kommentar von Tvde1 kann auch jede Number-Methode angewendet werden.

5..toString()

Mit dieser Syntax können wir die Number-Funktionen ohne Klammern ausführen.

5.toString() //error
(5).toString() //good
5..toString() //good
5 .toString() // awesome

In dieser Frage erfahren Sie, warum.

Charlie
quelle
4
Sie können sogar tun 5..toString().
Tvde1
2
In der Tat müssen Sie 5..toString () ausführen, um die Methode aufzurufen, andernfalls müssen Sie Klammern verwenden: (5) .toString ()
jo_va
3
@ PeterMortensen Ruby zum einen. Auch ALGOL 68. In Common Lisp ist seltsamerweise 1.0Gleitkomma, aber 1.eine ganze Zahl.
Sneftel
2
@FlorianF Das würdest du nicht, aber das bedeutet nicht, dass der Parser in einem speziellen Gehäuse sein sollte, um ihn abzulehnen. floats haben Methoden und 5.ist a float.
Chepner
2
@MasonWheeler Es ist sicherlich nicht der Fall, dass eine andere Sprache, in der dies (1).toMethod()legal ist, das (1.)ordnungsgemäße Parsen verbietet . Der traditionellste Ansatz zum Parsen (gieriges Lexen von Token, einschließlich Literalen, dann Parsen) erzeugt das Javascript-Verhalten.
Sneftel
7

Ich würde denken, dass es bei der eigentlichen Antwort nicht um den Dezimalpunkt geht, sondern um das Minuszeichen: Wird das nicht als Operator interpretiert, wenn ihm etwas vorausgeht, das wie eine Zahl aussieht?

Sean_999
quelle
1
Dann zumindest in einem gewissen Standpunkt aus, ist es nach wie vor ist etwa das Komma als Teil eines Zahlenliteral interpretiert werden, sonst , was das Minuszeichen vorangestellt würde nicht „sieht aus wie eine Nummer“.
Pac0
5

console.log(0. - 5)      // -5
console.log(0 - 5)       // -5
console.log('0.' - 5)    // -5
console.log('0' - 5)     // -5
console.log(0.-5 === -5) // true

'0.' oder '0' ist in JavaScript identisch, da der Typ für Zahlen eindeutig ist und als Zahl bezeichnet wird. Der Minus-Operator steht zwischen Zahlen. Versuchen Sie immer, das, was Sie übergeben, in eine Zahl umzuwandeln. In Python ist erstens ein Float und zweitens eine Integer anders, da es mehrere Typen gibt.

Κωλζαρ
quelle
Dieses Problem hat nichts mit Typen zu tun. Es hängt nur mit der Syntax zusammen.
user4642212