admin管理员组

文章数量:1320661

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"

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"
Share Improve this question edited Oct 11, 2012 at 9:04 user2428118 8,1244 gold badges46 silver badges73 bronze badges asked Oct 11, 2012 at 8:58 dfangdfang 1,38617 silver badges41 bronze badges 4
  • 2 Whya are you checking Number.isNaN? Do you mean this.isNaN()? – David Hellsing Commented Oct 11, 2012 at 9:04
  • In addition to the below answers, check out: 987654321..toMillion() – Izkata Commented Oct 11, 2012 at 13:57
  • 1 @David - It would just be isNaN(this) (it's a global function, not a property of Number.prototype). – James Allardice Commented Oct 11, 2012 at 13:58
  • @JamesAllardice right, it’s still very wrong in the post. Number.isNaN will never be truey unless the OP attached a static method to Number. – David Hellsing Commented Oct 11, 2012 at 17:32
Add a ment  | 

3 Answers 3

Reset to default 11

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 ments, 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.

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

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.

本文标签: prototypeWhat39s the difference between 987 and (987) in JavaScriptStack Overflow