Let’s ride on some WTF with JavaScript . Arrays [] == ![] This happens because of and . [precedence](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) [coercion](https://www.safaribooksonline.com/library/view/you-dont-know/9781491905159/ch04.html) Side note — Precedence determines the order from which operators are executed. The highest the precedence the sooner the operation will be performed. For instance, _*_ has an higher precedence than the operator _+_ . As for Coercion , this is JS ability to convert one of the operands (of an operator) to an “equivalent” value of the other operand. This happens when the operands’ type are different. For instance, for _boolean == integer_ , the _boolean_ operand will be converted into an _integer_ . Due to JS executes first the operation and then . [precedence](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) ![] == The operation negates the of and returns the boolean . On a : logical NOT ![] truthy [] false step-by-step Evaluate the expression ; [] Convert the result to boolean, i.e. . the result is ; ToBoolean([]) By definition true Return , which is the logical negation of ; false true We got **[] == false** . Now, it comes into play. [coercion](https://www.safaribooksonline.com/library/view/you-dont-know/9781491905159/ch04.html) Because our second operand is a boolean, the operation is translated into . of a boolean returns when or when (see the ). [] == ToNumber(false) ToNumber 1 true 0 false specification We got **[] == 0** . By , translates into , which in turn results into the operation . specification [] == 0 ToPrimitive([]) == 0 OrdinaryToPrimitive([], "number") == 0 for the parameters and runs both methods and of the and returns the result . In our case, because returns an object (i.e. ), the result of is returned instead (i.e. ). OrdinaryToPrimitive Object "number" **.valueOf()** **.toString()** Object which is not an object [].valueOf() [] [].toString() "" We got **"" == 0** . Patience. We are almost there 😅 Now, once the first operand is a string, our operation is translated into . , an empty string is converted into . ToNumber("") == 0 By definition 0 We got **0 == 0** . Which is 🎉 true There you go! Note: I went as deep I could on this first WTF to let you know how handy JS can be. For now on I’ll try to be more briefly. .apply() This “feature” is brought to you by . ECMAScript 5th Edition Starting with we can call with any . What this means is that ‘s second argument ( ) needs to have the property and the integer properties in the range . ES5 Function.prototype.apply() array-like object apply() see definition length 0…length — 1 For instance, the array has the property length of and the integer properties from (meaning, and .) So it’s an array-like object (this is a simple explanation, you can read the details .) [6,8] 2 0…1 [6,8][0] [6,8][1] here Because with the property , will execute the function with each value from as its arguments. all the 4 examples are array-like objects length apply() Array 0…length — 1 For the example it has a of and will execute as follows: {length: 3} length 3 apply() Array .sort() This is not a WTF. This is how works. But we can have fun anyway 😃 sort() According the , sorts the elements of an array according to their string unicode value. specification sort() Because the unicode value for first character of (i.e. ) is lower than the unicode value for the character , appears before when “sorting.” 10 1 2 10 2 I feel funny now! 🔥 .slice() You may all recall our friend which, according to its , “it takes two arguments, and , and ( not included”.) slice() specification start end returns an array containing the elements of the array from element **start** up to **end** end The syntax array.slice(begin, end) In both our examples, **begin** = 0. However, and although both and represent the absence of a value, the result for has nothing to do with the result for . null undefined **end** = null **end** = undefined The reason is ECMAScript Specification . Which says, if “ ”, then “ ”. **end** is undefined **end** is array’s length else “ ”, which translated into “ ”. toInteger ( **end** ) toNumber ( **end** ) By definition, is . **toNumber**(null) 0 Our statement is in fact . [1, 2, 3].slice(0, null) [1, 2, 3].slice(0, 0) You guessed it. That’s . [] 🍻 Thank you note: A HUGE thanks to @joaoffalcao for this WTF. < your WTF > 👐 If you find any WTF that should be here, please let me know That’s all for Arrays. Thanks to : MDN Documentation for his and Kyle Simpson video book for the Will Ferrel gifs guys, especially and , for reviewing 🦄 Paddy Power Betfair João Pedro The WTF contributor 👊 João Falcão for publishing ❤️ Hacker Noon Be sure to check out my other articles on JS WTF _Time to ride on some JavaScript WTF with Number._hackernoon.com JS WTF 🦄 with Number