Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between 987 and (987) in JavaScript?

I wrote a simple extension method.

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

987654321.toMillion() raises:

SyntaxError: Unexpected token ILLEGAL

But (987654321).toMillion() works.

So my question is: what's the difference between 987 and (987)?

Just FYI:

typeof(987) => returns "number"

And

typeof((987)) still returns "number"
like image 313
dfang Avatar asked Oct 11 '12 08:10

dfang


3 Answers

How would the parser know that the part following the . character is meant to signify a method call instead of another part of the number? For example:

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?

For that reason, you can't call methods on numeric literals. By placing the literal in parentheses (the grouping operator), the runtime will evaluate the contained expression and apply the method to the result of that evaluation.

The grouping operator removes the ambiguity of the . character.


Update

Following some thought and some investigation through the spec, there is a good reason to not allow the use of a lookahead to determine whether what follows the . character is part of the number or a property identifier.

As @CygnusX1 mentioned in the comments, you would have though that the two situations (. followed by a digit and . followed by a non-numeric character) could be differentiated by the use of a lookahead. Since identifiers can't start with a number, if a numeric character follows the ., it has to be a number. If a non-numeric character follows the ., it can't be part of the number. But that's not quite right.

There is one situation in which a non-numeric character can follow the . character but still be part of the number:

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

The e indicates that what follows is the exponent, and it can be either lowercase or uppercase. For this reason, using a lookahead would have to take into account that if the character following the . is e or E, it could still represent either a method or part of the number. It's easier to just disallow the use of properties on numeric literals.

like image 84
James Allardice Avatar answered Oct 14 '22 16:10

James Allardice


The . is overloaded in 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
like image 5
Torsten Walter Avatar answered Oct 14 '22 14:10

Torsten Walter


When 987654321.toMillion() is parsed "period" is interpreted as a delimiter of the fraction. So if you want to use number as an object you need to wrap it with braces.

like image 1
bjornd Avatar answered Oct 14 '22 14:10

bjornd