DEV Community

loading...
Cover image for Confusing JS Explained

Confusing JS Explained

ahmedgaafer profile image ahmedgaafer ・2 min read

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)

pic
Editor guide
Collapse
madza profile image
Madza • Edited

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 Sanfrancesco

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
π™ΌπšŠπš—πšžπšƒπš‘πšŽπ™²πš˜πšπšŽπš›

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