DEV Community

Cover image for Confusing JS Explained
ahmedgaafer
ahmedgaafer

Posted on

Confusing JS Explained

JavaScript, often abbreviated as JS, is a programming language that conforms to the ECMAScript specification. JavaScript is high-level, often just-in-time compiled, and multi-paradigm. It has curly-bracket syntax, dynamic typing, prototype-based object orientation, and first-class functions.

Some confusing parts

(([]+{})[1]+'mg').toUpperCase()  // outputs  OMG

Enter fullscreen mode Exit fullscreen mode

But how is this happening

We will go into a little depth on how JS interprets stuff

I am using chrome console to test all of this


Let's Explain the line above first

  • the '+' sign converts the parameters to strings by using the 'toPrimitive' method

  • so, toString([]) returns an empty string ''

  • and toString({}) returns to this '[object Object]'

  • then the result is '' + '[object Object]' = '[object Object]'

  • the rest is simple, I am picking the character at index 1 'o' and just adding the 'mg' and converting all to upper case

  • Drum roll ........

  • We get "OMG"


ToPrimitive:

ToPrimitive(input, PreferredType?)

The optional parameter PreferredType is either Number or String. It only expresses a preference, the result can always be any primitive value. If PreferredType is Number, the following steps are performed to convert a value input (ยง9.1):

  1. If the input is primitive, return it as is.
  2. Otherwise, input is an object. Call obj.valueOf(). If the result is primitive, return it.
  3. Otherwise, call obj.toString(). If the result is primitive, return it.
  4. Otherwise, throw a TypeError.

If PreferredType is String, steps 2 and 3 are swapped. If PreferredType is missing then it is set to Number for any numeric values and to string for all other values.


1 + 1       //    2    <= Number
1 + 1 + '1' //   '21'  <= String
1 + 1 + []  //    '2'  <= String

Enter fullscreen mode Exit fullscreen mode

There are some unique examples that behave differently

{} + 1  // 1 <= Number

// JS treats the '{}' in this case as its own line 

({});+1 = 1

({})+1 = '[object Object]1'


Enter fullscreen mode Exit fullscreen mode

Now you can apply this principle to any addition in JS and always know the answer without being confused


references:

JSInfo
MDN

Discussion (7)

Collapse
madza profile image
Madza • Edited on

If you are into this kind of stuff, I would recommend wtfjs ๐Ÿ˜‰
For example, did you know that:

(![] + [])[+[]] +
(![] + [])[+!+[]] +
([![]] + [][[]])[+!+[] + [+[]]] +
(![] + [])[!+[] + !+[]];
// -> 'fail'

Recruiters love it, too ๐Ÿ˜€๐Ÿ˜€

Collapse
tqbit profile image
tq-bit

Came for the meme, stayed for the code.
Stuff like this is the reason why I love javascript.
Had my first wtf moment when trying:

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

Collapse
devendra0110 profile image
Devendra Gaud

Can you explain it?

Collapse
sanfra1407 profile image
Giuseppe

When your run 'a' + + 'a' you're doing 'a' + +'a'. JavaScript tries to cast +'a' to a number which is cleary impossible; so it returns NaN (Not a Number) and then it concatenates the NaN to other chars, creating the baNaNa string. The magic happens with the toLowerCase() method :)

Collapse
kingsleyijomah profile image
Kingsley Ijomah

I defo learnt something new here! thanks bro!

Collapse
manuthecoder profile image
ManuTheCoder

Interesting JS.
I was wondering, where would you use this code though?
Like in which case?

Collapse
ahmedgaafer profile image
ahmedgaafer Author

You wouldn't normally use this.

This is just to know the expected behavior of js and how it works