Why is the result of ('b'+'a'+ + 'a' + 'a').toLowerCase() 'banana'?

JavascriptType Conversion

Javascript Problem Overview


I was practicing some JavaScript when one of my friends came across this JavaScript code:

document.write(('b' + 'a' + + 'a' + 'a').toLowerCase());

The above code answers "banana"! Can anyone explain why?

Javascript Solutions


Solution 1 - Javascript

+'a' resolves to NaN ("Not a Number") because it coerces a string to a number, while the character a cannot be parsed as a number. document.write(+'a'); To lowercase it becomes banana.

Adding NaN to "ba" turns NaN into the string "NaN" due to type conversion, gives baNaN. And then there is an a behind, giving baNaNa.

The space between + + is to make the first one string concatenation and the second one a unary plus (i.e. "positive") operator. You have the same result if you use 'ba'+(+'a')+'a', resolved as 'ba'+NaN+'a', which is equivalent to 'ba'+'NaN'+'a' due to type juggling.

document.write('ba'+(+'a')+'a');

Solution 2 - Javascript

'b' + 'a' + + 'a' + 'a'

...is evaluated as....

'b' + 'a' + (+'a') + 'a'

(see: operator precedence)

(+'a') attempts to convert 'a' to a number using the unary plus operator. Because 'a' is not a number, the result is NaN ("Not a Number"):

'b'  +  'a'  +  NaN  + 'a'

Although NaN stands for "Not a Number", it's still a numeric type; when added to strings, it concatenates just as any other number would:

'b'  +  'a'  +  NaN  + 'a'  =>  'baNaNa'

Finally, it's lowercased:

'baNaNa'.toLowerCase()      =>  'banana'

Solution 3 - Javascript

('b' + 'a' + + 'a' + 'a').toLowerCase()

For clarity, let's break this down into two steps. First, we get the value of the parenthesized expression and then we apply the toLowerCase() function on the result.

Step one

'b' + 'a' + + 'a' + 'a' Going L-R, we have:

  • 'b' + 'a' returns ba, this is regular concatenation.
  • ba + + 'a' attempts to concatenate ba with + 'a'. However, since the unary operator + attempts to convert its operand into a number, the value NaN is returned, which is then converted into a string when concatenated with the original ba - thus resulting in baNaN.
  • baNaN + 'a' returns baNaNa. Again, this is regular concatenation.

> At this stage, the result from step one is baNaNa.

Step two

Applying .toLowerCase() on the value returned from step one gives:

> banana

There are many similar puns in JavaScript that you can check out.

Solution 4 - Javascript

It's just because of + operator.

We can get further knowledge from chunk it.

=> ( ('b') + ('a') + (++) + ('a') + ('a'))
=> ( ('b') + ('a') + (+) + ('a') + ('a')) // Here + + convert it to +operator 
Which later on try to convert next character to the number.

For example

const string =  '10';

You can convert a string into number by 2 ways:

  1. Number(string);
  2. +string;

So back to the original query; Here it tries to convert the next char ('a') to the number but suddenly we got error NaN,

( ('b') + ('a') + (+'a') + ('a'))
( ('b') + ('a') + NaN + ('a'))

But it treats as a string because the previous character was in the string. So it will be

( ('b') + ('a') + 'NaN' + ('a'))

And last it converts it to toLowerCase(), So it would be banana

If you are put number next to it, Your result will be change.

( 'b' + 'a' +  + '1' + 'a' ) 

It would be 'ba1a'

const example1 = ('b' + 'a' + + 'a' + 'a').toLowerCase(); // 'banana' 
const example2 = ('b' + 'a' + + '1' + 'a').toLowerCase(); // 'ba1a'
console.log(example1);
console.log(example2);

Solution 5 - Javascript

This line of code evaluates an expression and then calls a method based on the returned value.

The expression ('b' + 'a' + + 'a' + 'a') is solely composed of string literals and addition operators.

> - String Literals "A string literal is zero or more characters enclosed in single or double quotes." > - The Addition operator ( + ) "The addition operator either performs string concatenation or numeric addition."

An implicit action taken is the call for ToNumber on a string

> - ToNumber Applied to the String Type "ToNumber applied to Strings applies grammar to the input String. If the grammar cannot interpret the String as an expansion of StringNumericLiteral, then the result of ToNumber is NaN."

The interpreter has rules of how to parse the expression, by breaking it down into its components of left and right hand expressions.


Step 1: 'b' + 'a'

Left Expression: 'b'
Left Value: 'b'

Operator: + (one of the expression sides is a string, so string concatenation)

Right Expression: 'a' Right Value: 'a'

Result: 'ba'


Step 2: 'ba' + + 'a'

Left Expression: 'ba'
Left Value: 'ba'

Operator: + (one of the expression sides is a string, so string concatenation)

Right Expression: + 'a' (this evaluates the Math Value of the character 'a' assuming that it is a positive number from the + sign -- the minus sign would have also worked here indicating a negative number -- which results in NaN)
Right Value: NaN (because the operator is string concatenation, toString is called on this value during concatenation)

Result: 'baNaN'


Step 3: 'baNaN' + 'a'

Left Expression: 'baNaN'
Left Value: 'baNaN'

Operator: + (one of the expression sides is a string, so string concatenation)

Right Expression: 'a'
Right Value: 'a'

Result: 'baNaNa'


After this the grouping expression has been evaluated, and toLowerCase is called which leaves us with banana.

Solution 6 - Javascript

Using + will convert any value to Number in JavaScript!

So...

The main thing here to know first and learn from is using + before any value in JavaScript, will convert that value to a number, but if that value can not be converted, JavaScript engine will return NaN, which means, not a number (can not be converted to a number, mate!) and the rest of story as below:

Why is the result of ('b'+'a'+ + 'a' + 'a').toLowerCase()'banana'?

Solution 7 - Javascript

enter image description here

Read more about NaN at W3Schools or Mozilla Developer Network

Solution 8 - Javascript

See the magic here. Second plus is an unary operator which gives 'NaN'

console.log(('b' + 'a' + + 'a' + 'a').toLowerCase());
console.log(('b' + 'a' + + 'a' + 'a'));
console.log(('b' + 'a' + 'a' + 'a').toLowerCase());

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHV SharmaView Question on Stackoverflow
Solution 1 - JavascriptSOFeView Answer on Stackoverflow
Solution 2 - JavascriptTyler RoperView Answer on Stackoverflow
Solution 3 - JavascriptTaslim OseniView Answer on Stackoverflow
Solution 4 - JavascriptNeel RathodView Answer on Stackoverflow
Solution 5 - JavascriptTravis JView Answer on Stackoverflow
Solution 6 - JavascriptAlirezaView Answer on Stackoverflow
Solution 7 - JavascriptrprakashView Answer on Stackoverflow
Solution 8 - JavascriptRakibul IslamView Answer on Stackoverflow