Why must I wrap a number to call its methods? - javascript

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"

Related

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

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()

String.fromCharCode() does not work after the value "126"

I have been trying the following code to get the ASCII equivalent character
String.fromCharCode("149")
but, it seems to work till 126 is passed as parameter. But for 149, the symbol generated should be
•
128 and beyond is not standard ASCII.
var s = "•";
alert(s.charCodeAt(0))
gives 8226
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode
Getting it to work with higher values Although most common Unicode
values can be represented with one 16-bit number (as expected early on
during JavaScript standardization) and fromCharCode() can be used to
return a single character for the most common values (i.e., UCS-2
values which are the subset of UTF-16 with the most common
characters), in order to deal with ALL legal Unicode values (up to 21
bits), fromCharCode() alone is inadequate. Since the higher code point
characters use two (lower value) "surrogate" numbers to form a single
character, String.fromCodePoint() (part of the ES6 draft) can be used
to return such a pair and thus adequately represent these higher
valued characters.
The fromCharCode() method converts Unicode values into characters.
to use unicode see the link for unicode table
http://unicode-table.com/en/
I got String.fromCodePoint(149) to show inside an alert in firefox but not in IE & Chrome. It may be because of browser language settings.
But this looks correct accourding to the ASCII table.
http://www.asciitable.com/
This is the code I used
alert(String.fromCodePoint(149));

+ operator vs parseFloat

Example 1 of the knockout extenders page describes a way of rounding user input and making sure it is only numeric.
It works great, but looking through the source they do a peculiar thing that i don't understand, that is on line 8 they do this:
parseFloat(+newValue)
newValue is a string.
When i initially asked this question I didn't know what + did - some further poking and a link to a different MDN page from one of the initial answers I got indicate it is a unary operator equivalent to number(str) and that there are some differences between +str and parseFloat(str) (treatment of strings ending in alpha characters and interpretation of hex seem to be the headlines).
I still don't understand why the + in this case needed to be wrapped in the parseFloat although I am starting to think it might be a typo...
Citing MDN docs for parseFloat:
parseFloat parses its argument, a string, and returns a floating point number. If it encounters a character other than a sign (+ or -), numeral (0-9), a decimal point, or an exponent, it returns the value up to that point and ignores that character and all succeeding characters. Leading and trailing spaces are allowed.
Using [unary plus operator][2] you may be sure that `parseFloat` operates on `Number`, which is only useful if you want to be more strict about results but still want to use a `parseFloat`
parseFloat('0.32abcd') // -> 0.32
parseFloat(+'0.32abcd') // -> NaN
**Update:**
After a bit of digging in docs and running some tests, seems there is no reason to use parseFloat other than parsing strings that may contain numbers with non numeric trails to number, eq:
parseFloat('31.5 miles') // -> 31.5
parseFloat('12.75em') // -> 12.75
For any other cases where your string contains number + is a fastest and prefered way (citing MDN docs for unary plus operator):
unary plus is the fastest and preferred way of converting something into a number, because it does not perform any other operations on the number.
See parseFloat versus unary test case for how faster it is.
Previous link broken so here is the new test that shows how unary is faster.

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"

eval creating problems in evaluating

i am using eval to convert string decimals to decimals.
eval("000451.01");
When i am using the above statement javascript it throws exception 'expected ;'
and when using eval("000451"); it gives me a different result.
anyone has got any idea??
You should not use eval to parse numbers; it will be orders of magnitude slower than normal methods.
Instead, you should use the parseFloat function. like this: parseFloat("000451.01").
The reason you're getting the error is that Javascript treats numbers that begin with 0 as octal numbers, which cannot have decimals.
If you want to parse an integer, call parseInt, and make sure to give a second parameter of 10 to force it to parse base 10 numbers, or you'll get the same problem.
In Javascript, a token starting with zero is an integer literal in base 8. 000451 in base 8 is 297 in base 10, and 000451.01 is parsed as int(297) dot int(1) instead of a single number literal.
Remove the initial zeros and it should work.
Numbers starting with a zero are interpreted as octal numbers. But octal numbers are only integers and not floating point numbers. So try this:
eval("451.01")
But it would be better if you use the parseFloat function:
parseFloat("000451.01")

Categories