2012-10-11 12 views
8

Napisałem prostą metodę rozszerzenia.Jaka jest różnica między 987 a (987) w JavaScript?

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

987654321.toMillion() podnosi:

SyntaxError: Unexpected token ILLEGAL

Ale (987654321).toMillion() prace.

Moje pytanie brzmi: jaka jest różnica między 987 i (987)?

Wystarczy FYI:

typeof(987) => returns "number" 

I

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

Czy sprawdzasz 'Number.isNaN'? Masz na myśli 'this.isNaN()'? – David

+0

Oprócz poniższych odpowiedzi, sprawdź: '987654321..toMillion()' – Izkata

+1

@David - To byłoby po prostu 'isNaN (this)' (jest to funkcja globalna, a nie właściwość 'Numer.prototype'). –

Odpowiedz

11

Jak parser wie, że część po znaku . ma oznaczać wywołanie metody zamiast kolejną część numeru? Na przykład:

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? 

Z tego powodu nie można wywoływać metod na literałach numerycznych. Umieszczając literał w nawiasie (the grouping operator), środowisko wykonawcze oceni zawarte wyrażenie i zastosuje metodę do wyniku tej oceny.

Operator grupujący usuwa niejednoznaczność znaku ..


Aktualizacja

Po namyśle i niektóre dochodzenia przez spec, to jest dobry powód, aby nie zezwolić na stosowanie uprzedzona do ustalenia, czy co następuje znak . jest częścią numeru lub identyfikator nieruchomości.

Jako @ CygnusX1 wspomniano w komentarzach, trzeba jednak, że te dwie sytuacje (. obserwowani przez cyfry i . następnie charakterze non-numerycznej) może być zróżnicowana w zależności od zastosowania uprzedzona. Ponieważ identyfikatory nie mogą zaczynać się od liczby, jeśli znak numeryczny podąża za ., musi to być liczba. Jeśli znak nieliczbowy podąża za ., nie może być częścią tej liczby. Ale to nie w porządku.

Jest jedna sytuacja, w której postać nienumeryczny może obserwować charakter . ale nadal być częścią numeru:

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

e wskazuje, że co za tym idzie jest wykładnik, a może być małymi lub wielkimi literami. Z tego powodu użycie wyprzedzenia musiałoby uwzględniać fakt, że jeśli znak następujący po . jest nadal zgodny, może nadal reprezentować metodę lub część tej liczby. Łatwiej jest po prostu zabronić używania właściwości literałów numerycznych.

+0

Uderzyłeś mnie w to;) –

+0

Parser może zdecydować o tym, patrząc w przyszłość. Jeśli element za kropką jest identyfikatorem, to kropka nie powinna być częścią numeru. Jednakże, jak na przykład Torstena Waltera - ponieważ członkowie mogą być same liczbami, nie jest to już możliwe. – CygnusX1

+0

@ CygnusX1 - Drugi przykład Torstena jest błędem składni. Nie można zdefiniować takich właściwości liczbowych (ponieważ identyfikatory nie mogą zaczynać się od liczby). –

5

The . jest przeciążony w JavaScript.

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

Zauważ, że Twój drugi przykład faktycznie zgłasza błąd składni, ponieważ identyfikator nie może zaczynać się od liczby. –

1

Gdy 987654321.toMillion() jest analizowany „okres” jest interpretowany jako ogranicznik frakcji. Więc jeśli chcesz użyć liczby jako obiektu, musisz go owinąć klamrami.

Powiązane problemy