2012-10-11 18 views
8

Ich schrieb eine einfache Erweiterungsmethode.Was ist der Unterschied zwischen 987 und (987) in JavaScript?

Number.prototype.toMillion = function(){ 
if(!Number.isNaN){ 
    return this/1000000; 
} 
} 

987654321.toMillion() aufwirft:

SyntaxError: Unexpected token ILLEGAL

Aber (987654321).toMillion() funktioniert.

Also meine Frage ist: Was ist der Unterschied zwischen 987 und (987)?

Gerade FYI:

typeof(987) => returns "number" 

Und

typeof((987)) still returns "number" 
+2

Warum überprüfen Sie 'Number.isNaN'? Meinst du "this.isNaN()"? – David

+0

Zusätzlich zu den folgenden Antworten, check out: '987654321..toMillion()' – Izkata

+1

@David - Es wäre nur 'isNaN (this)' (es ist eine globale Funktion, keine Eigenschaft von 'Number.prototype'). –

Antwort

11

Wie würde der Parser wissen, dass der Teil nach dem . Charakter einen Methodenaufruf, um anzuzeigen, anstatt einen anderen Teil der Anzahl gemeint? Zum Beispiel:

10.1 // This is a number with a floating point 
10.toMillion() //How does it know that this shouldn't be part of the number? 

Aus diesem Grunde können Sie diese Methoden nicht auf Zahlenliterale nennen. Wenn Sie das Literal in Klammern setzen (grouping operator), bewertet die Laufzeitumgebung den enthaltenen Ausdruck und wendet die Methode auf das Ergebnis dieser Auswertung an.

Der Gruppierungsoperator entfernt die Mehrdeutigkeit des .-Zeichens.


aktualisiert

Nach einigem Nachdenken und einige Untersuchungen durch die Spezifikation gibt es einen guten Grund, nicht der Verwendung eines Look-Ahead erlauben zu bestimmen, ob, was folgt den . Charakter ist Teil der Nummer oder eine Eigenschaftskennung.

Wie @ CygnusX1 in den Kommentaren erwähnt, hätten Sie jedoch, dass die beiden Situationen (. gefolgt von einer Ziffer und . gefolgt von einem nicht numerischen Zeichen) durch die Verwendung eines Lookahead unterschieden werden könnte. Da Bezeichner nicht mit einer Nummer beginnen können, muss ein numerisches Zeichen nach dem . eine Zahl sein. Wenn dem . ein nicht numerisches Zeichen folgt, kann es nicht Teil der Nummer sein. Aber das ist nicht ganz richtig.

Es ist eine Situation, in der ein nicht-numerischen Zeichen der . Zeichen folgen können, aber immer noch Teil der Zahl sein:

console.log(1.e5); // Logs '100000' 

Die e zeigt an, dass, was folgt, ist der Exponenten, und es kann sei entweder Klein- oder Großbuchstaben. Aus diesem Grund muss bei der Verwendung eines Lookahead berücksichtigt werden, dass das Zeichen, das dem .e oder E folgt, immer noch eine Methode oder einen Teil der Zahl darstellen kann. Es ist einfacher, die Verwendung von Eigenschaften für numerische Literale einfach zu verbieten.

+0

Sie haben mich dazu geschlagen;) –

+0

Der Parser könnte es entscheiden, indem er vorausblickt. Wenn das Element nach Punkt ein Bezeichner ist, sollte der Punkt kein Teil der Nummer sein. Aber nach Torsten Walters Beispiel - da Mitglieder selbst Nummern sein können, ist dies nicht mehr möglich. – CygnusX1

+0

@ CygnusX1 - Torstens zweites Beispiel ist ein Syntaxfehler. Sie können numerische Eigenschaften wie diese nicht definieren (da Bezeichner nicht mit einer Zahl beginnen können). –

5

Die . ist in JavaScript überladen.

123.123   // the interpreter assumes this is a floating point number 
(123).123  // throws a syntax error, since an identifier 
       // can't start with a number. - thanks James for pointing that out 
(123).toMillion // refers to the function of the object returned by 
       // the statement in braces 
123.toMillion // will throw a syntax error because a floating point number has only digits 
+1

Beachten Sie, dass Ihr zweites Beispiel tatsächlich einen Syntaxfehler auslöst, da ein Bezeichner nicht mit einer Zahl beginnen kann. –

1

Wenn 987654321.toMillion() analysiert wird „period“ wird als ein Trennzeichen der Fraktion interpretiert. Wenn Sie die Zahl als Objekt verwenden möchten, müssen Sie sie mit geschweiften Klammern umbrechen.

Verwandte Themen