Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird behavior when using + + in JavaScript

Everybody knows the basic concatenation of two strings in JavaScript:

> "Hello " + "World!"
'Hello World!'

But what happens if we use + + instead of +? I just encountered the following weird behavior:

> "Hello " + + "World!"
'Hello NaN'
> "Hello " + + ""
'Hello 0'

From the examples above, I can see that the second string is converted into number. So, passing an object having valueOf property as function, the value returned by that function will be converted.

> "Hello " + + ({valueOf: function () {return 1; }})
'Hello 1'

As expected, it shows "Hello 1".


Why is the second string converted in Number? Why not throwing a syntax error or so?

like image 387
Ionică Bizău Avatar asked Aug 27 '14 17:08

Ionică Bizău


People also ask

What are the issues with JavaScript?

These days, most cross-browser JavaScript problems are seen: When poor-quality browser-sniffing code, feature-detection code, and vendor prefix usage block browsers from running code they could otherwise use just fine. When developers make use of new/nascent JavaScript features, modern Web APIs, etc.)

Why is JavaScript so strange?

While foreign and strange at first, JavaScript solves problems in a truly elegant, intelligent, and even logical way. The very thing that makes JavaScript weird is the same thing that makes it powerful. It can feel uncomfortable to write JavaScript at first. But the more you use it, the more it becomes second nature.

Does JavaScript have undefined behavior?

Is there a piece of JavaScript code for which the behaviour is not completely determined by the JavaScript specifications, and, as such, has "undefined behaviour"? Yes, read the quirksmode.


3 Answers

The second + is the unary plus operator whose purpose is to convert its operand to a number.

The unary plus operator precedes its operand and evaluates to its operand but attempts to converts it into a number, if it isn't already. Although unary negation (-) also can convert non-numbers, 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. It can convert string representations of integers and floats, as well as the non-string values true, false, and null. Integers in both decimal and hexadecimal ("0x"-prefixed) formats are supported. Negative numbers are supported (though not for hex). If it cannot parse a particular value, it will evaluate to NaN.

"Hello " + + "World!"

can only be parsed as

"Hello " + (+ "World!")

which is

"Hello " + NaN

hence your result.

This unary operator is very useful in JavaScript and is one of the most common ways to convert from something which may be a number or a string to a number. It also has the advantage over parseFloat that it's not ridiculously tolerant (parseFloat("7up") would return 7) which makes it an easy way to see if a string is the representation of a number (just test s==+s).

like image 99
Denys Séguret Avatar answered Oct 17 '22 15:10

Denys Séguret


Great question. This is because JavaScript has a unary + operator (similar to the unary - as in, ex, -1, which is parsed to - (1)): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus_(.2B)

Thus "foo" + + "bar" is parsed to "foo" + (+ "bar") (or if you prefer a lisp-style parse tree: (+ "foo" (+ "bar")).

The unary + converts its operand to a number, or NaN if the operand isn't a sensible number:

> +"42"
42
> +"foo"
NaN

Finally, adding a number (including NaN) to a string results in a string concatenation.

Thus "foo" + +"bar" can be expanded:

"foo " + +"bar"
"foo " + NaN
"foo NaN"
like image 32
David Wolever Avatar answered Oct 17 '22 15:10

David Wolever


Here + is a unary plus operator Which tries to convert the operator in number & works as follows

+"" //return 0
+"Some" //returns NaN

So here

"Hello " + + "World!" 

will be

"Hello " + (+ "World!")
"Hello " + NaN
"Hello Nan"
like image 30
Mritunjay Avatar answered Oct 17 '22 16:10

Mritunjay