Why cannot I use number as immediate value? [duplicate] - javascript

If I try to write
3.toFixed(5)
there is a syntax error. Using double dots, putting in a space, putting the three in parentheses or using bracket notation allows it to work properly.
3..toFixed(5)
3 .toFixed(5)
(3).toFixed(5)
3["toFixed"](5)
Why doesn't the single dot notation work and which one of these alternatives should I use instead?

The period is part of the number, so the code will be interpreted the same as:
(3.)toFixed(5)
This will naturally give a syntax error, as you can't immediately follow the number with an identifier.
Any method that keeps the period from being interpreted as part of the number would work. I think that the clearest way is to put parentheses around the number:
(3).toFixed(5)

You can't access it because of a flaw in JavaScript's tokenizer. Javascript tries to parse the dot notation on a number as a floating point literal, so you can't follow it with a property or method:
2.toString(); // raises SyntaxError
As you mentioned, there are a couple of workarounds which can be used in order make number literals act as objects too. Any of these is equally valid.
2..toString(); // the second point is correctly recognized
2 .toString(); // note the space left to the dot
(2).toString(); // 2 is evaluated first
To understand more behind object usage and properties, check out the Javascript Garden.

It doesn't work because JavaScript interprets the 3. as being either the start of a floating-point constant (such as 3.5) or else an entire floating-point constant (with 3. == 3.0), so you can't follow it by an identifier (in your case, a property-name). It fails to recognize that you intended the 3 and the . to be two separate tokens.
Any of your workarounds looks fine to me.

This is an ambiguity in the Javascript grammar. When the parser has got some digits and then encounters a dot, it has a choice between "NumberLiteral" (like 3.5) or "MemberExpression" (like 3.foo). I guess this ambiguity cannot be resolved by lookahead because of scientific notation - should 3.e2 be interpreted as 300 or a property e2 of 3? Therefore they voluntary decided to prefer NumberLiterals here, just because there's actually not very much demand for things like 3.foo.

As others have mentioned, Javascript parser interprets the dot after Integer literals as a decimal point and hence it won't invoke the methods or properties on Number object.
To explicitly inform JS parser to invoke the properties or methods on Integer literals, you can use any of the below options:
Two Dot Notation
3..toFixed()
Separating with a space
3 .toFixed()
Write integer as a decimal
3.0.toFixed()
Enclose in parentheses
(3).toFixed()
Assign to a constant or variable
const nbr = 3;
nbr.toFixed()

Related

Why do you have to wrap parenthesis around a number to called toFixed on it?

For example,
1.toFixed(2) // Uncaught SyntaxError: Invalid or unexpected token
(1).toFixed(2) // "1.00"
let num = 1
num.toFixed(2) // "1.00"
At the same time, you don't have to wrap parenthesis around strings to call methods on them
'yo'.repeat(3) // "yoyoyo"
What is the rule at play here and where else does it apply? Guessing it has something to do with the dot being misinterpreted as a decimal for numbers?
Because the interpreter is looking for more digits (decimal values), not keywords or methods.
As others have stated, JavaScript is looking for more numbers after the decimal point. It thinks you are trying to type a float like 1.2 and it doesn't like that t there, it's not a number.
Interestingly, you can do this without parenthesis or making variable by using 2 decimal points. Like this: 1..toFixed(2). I guess you can also do 1.0.toFixed(2) if you want.
When using a variable, Javascript is confident that you're not going to add decimals after the point.
When not using a variable, Javascript thinks that you are going to add decimals after the point.
When you wrap your number with parenthesis, you say that the number is finished, and everything is fine again.
You can also use .. if you don't like parenthesis. The first one for decimals, the second one to call the method.
let num = 1;
console.log(num.toFixed(2));
// console.log(1.toFixed(2)); // ERROR
console.log((1).toFixed(2));
console.log(1..toFixed(2));

What is the critical difference between 'Number.parseInt()', 'Number.parseFloat()', 'Number()' or '+'?

The basic question here is how do I know when to use and
what is the critical difference between each of them:
The Number.parseInt method (or just parseInt),
Number.parseFloat method (or just parseFloat),
Number() function (or class?),
and the + operator
for converting JavaScript values (mostly String's) to numbers.
Especially since all of them give similar values and can convert String to its Number representation:
Number.parseInt("2") // returns 2
Number.parseFloat("2") // returns 2
Number("2") // returns 2
+"2" // returns 2
/* Plus a few more methods... */
eval("2") // returns 2
JSON.parse("2") // returns 2
Number.parseInt method (or just parseInt)
Ignores leading and trailing whitespace
Parses a leading number to an integer (not a floating point number)
Ignores invalid trailing data
Lets you set the base to use when interpreting the number
Will interpret text starting with 0x as hexadecimal, if another base was not provided
Returns NaN if the value could not be successfully parsed to an integer
Number.parseFloat method (or just parseFloat)
Similar to parseInt, except that it allows for a decimal part to be interpreted
Only parses to base-10
Number() function (or class?)
Similar to parseFloat, but does not allow trailing text
Will return 0 for an empty string or a string that only contains whitespace
It's not a class; when called without new, it returns a primitive number
the + operator
Basically the same as Number(), but in operator form.
eval()
Interprets and executes the given input as a JavaScript program.
Given the string "2", it will be interpreted as a numeric literal, and return that value since it's the result of the last expression in the program
Throws an error if the input was not a valid program.
JSON.parse()
Parses the textual data as JSON-serialized data.
If the data is valid, it creates the JavaScript objects/primitives that are represented by the data, and returns them.
If the data is invalid, it throws an error.
Given the string "2", it will be interpreted as a numeric literal, and return the value that was successfully parsed out of it according to the parsing requirements of JSON.
So you decide which is appropriate to use based on their capabilities.
Number.parseInt() calls the global function parseInt() in the background, same with Number.parseFloat() see: Number.parseInt ECMA and Number.parseFloat ECMA
The calls Number("2") and "+2" is identical in the background, they both call ToNumber see: Number and Unary + Operator
When you know what types you are working with, or want a guaranteed type back, use parseFloat and parseInt, otherwise it tends to be easier to only use Number() as it will work within all your calculations, many people choose to use the unary + operator because they find it more pleasing to read/type, but that is only based on preference as it is identical to Number().
Also, when you using parseInt(), you can specify a radix, which is useful in certain applications where you want to work in different number systems, which you cannot do with Number()
If the ECMA standard references does not explain the details for you enough, I will add a summary for you.

Why does 10..toString() work, but 10.toString() does not? [duplicate]

This question already has answers here:
Closed 10 years ago.
 
Why does calling 152..toString(2) return a binary string value of "10011000", when a call to 152.toString(2) throws the following exception?
          "SyntaxError: identifier starts immediately after numeric literal"
It seems to me that it's intuitive to want to use the latter call to toString(), as it looks & feels correct. The first example just seems plain odd to me.
Does anyone know why JavaScript was designed to behave like this?
A . after a number might seem ambiguous. Is it a decimal or an object member operator?
However, the interpreter decides that it's a decimal, so you're missing the member operator.
It sees it as this:
(10.)toString(); // invalid syntax
When you include the second ., you have a decimal followed by the member operator.
(10.).toString();
#pedants and downvoters
The . character presents an ambiguity. It can be understood to be the member operator, or a decimal, depending on its placement. If there was no ambiguity, there would be no question to ask.
The specification's interpretation of the . character in that particular position is that it will be a decimal. This is defined by the numeric literal syntax of ECMAScript.
Just because the specification resolves the ambiguity for the JS interpreter, doesn't mean that the ambiguity of the . character doesn't exist at all.
The lexer (aka "tokenizer") when reading a new token, and upon first finding a digit, will keep consuming characters (i.e. digits or one dot) until it sees a character that is not part of a legal number.
<152.> is a legal token (the trailing 0 isn't required) but <152..> isn't, so your first example reduces to this series of tokens:
<152.> <.> <toString> <(> <2> <)>
which is the legal (and expected) sequence, whereas the second looks like
<152.> <toString> <(> <2> <)>
which is illegal - there's no period token separating the Number from the toString call.
10. is a float number an you can use toString on float
eg.
parseFloat("10").toString() // "10"

javascript number property syntax [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why can't I access a property of an integer with a single dot?
I was reading an article, and came across the strange behaviour of javascript toFixed method. I don't understand the reason for the last statement. Can anyone explain please?
(42).toFixed(2); // "42.00" Okay
42.toFixed(2); // SyntaxError: identifier starts immediately after numeric literal
42..toFixed(2); // "42.00" This really seems strange
A number in JavaScript is basically this in regex:
[+-]?[0-9]*(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?
Note that the quantifiers are greedy. This means when it sees:
42.toFixed(2);
It reads the 42. as the number and then is immediately confronted with toFixed and doesn't know what to do with it.
In the case of 42..toFixed(2), the number is 42. but not 42.. because the regex only allows one dot. Then it sees the . which can only be a call to a member, which is toFixed. Everything works fine.
As far as readability goes, (42).toFixed(2) is far clearer as to its intention.
The dot is ambiguous: decimal point or call member operator. Therefore the error.
42..toFixed(2); is equivalent to (42.).toFixed(2)

Why must I wrap a number to call its methods?

js> (5).toString(2)
101
js> 5.toString(2)
js: "<stdin>", line 53: missing ; before statement
js: 5.toString(2)
js: ..........^
js>
Javascript assumes (bizarrely) that a number followed by a dot means the dot is a decimal point. This is counter-intuitive, but at least it's reliable.
You have several choices as to how you deal with this:
(5).toString(2); #1
5..toString(2); #2
5.0.toString(2); #3
5 .toString(2); #4
Stackoverflow's syntax highlighter shows you that, in #2 and #3, the first dot is considered to be part of the number and the second to be the operator. In #4, we can see that the space tells the parser that the number has ended.
Because without the parentheses, the dot in 5.toString() is interpreted as a decimal point. Without parentheses, the interpreter interprets that sequence of characters as a floating point literal.
In Javascript, numbers may be floating point, so 5.0 is a valid number. When you use 5.toString, it looks like toString is the fractional part of the number. Javascript's parser does not handle this case.
Some other languages (such as Ruby) handle this differently.
The interpreter tries to parse the . as a decimal point first, thus it expects toString to be a numeral. Note that the following works since it already has received the decimal:
js> 5.0.toString(2); // -> "101"

Categories