Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 348
HV Sharma Avatar asked Aug 12 '19 05:08

HV Sharma


5 Answers

+'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');
like image 86
SOFe Avatar answered Oct 22 '22 06:10

SOFe


'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'
like image 113
Tyler Roper Avatar answered Oct 22 '22 05:10

Tyler Roper


('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.

like image 49
Taslim Oseni Avatar answered Oct 22 '22 06:10

Taslim Oseni


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);
like image 27
Neel Rathod Avatar answered Oct 22 '22 06:10

Neel Rathod


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.

like image 11
Travis J Avatar answered Oct 22 '22 06:10

Travis J