
1. Arrays and Equality
[]==![];// -> true// Explanation: Arrays are truthy, so ![] is false, which coerces to 0. [] coerces to 0, so 0 == 0 is true.true==[];// -> falsetrue==![];// -> false// Explanation: true converts to 1 and [] converts to 0. 1 != 0.false==[];// -> truefalse==![];// -> true// Explanation: false and [] both convert to 0. 0 == 0.
2. Type Coercion Oddities
!!"false"==!!"true";// -> true// Explanation: Both strings are truthy, so !! converts them to true."b"+"a"++"a"+"a";// -> 'baNaNa'// Explanation: +"a" converts 'a' to NaN, so it becomes "ba" + NaN + "a" which is 'baNaNa'.NaN===NaN;// -> false// Explanation: NaN is not equal to anything, including itself.
3. Object Comparison
Object.is(NaN,NaN);// -> trueNaN===NaN;// -> false// Explanation: Object.is and === have different behaviors for NaN.Object.is(-0,0);// -> false-0===0;// -> true// Explanation: -0 and 0 are considered equal with === but not with Object.is.
4. Fun with Syntax
[1,2,3]+[4,5,6];// -> '1,2,34,5,6'// Explanation: Arrays are converted to strings and concatenated.leta=[,,,];a.length;// -> 3// Explanation: Trailing commas create empty slots, affecting array length.
5. Number Coercion and Parsing
parseInt(null,24);// -> 23// Explanation: null is converted to a string and then parsed according to the specified radix.0.1+0.2;// -> 0.30000000000000004// Explanation: Floating-point arithmetic can produce imprecise results.true+true;// -> 2(true+true)*true-true;// -> 1// Explanation: Booleans are coerced to numbers in arithmetic operations.Number();// -> 0Number(undefined);// -> NaN// Explanation: Number without arguments returns 0, with undefined returns NaN.
6. Unexpected Typeof and Instanceof
typeofNaN;// -> 'number'// Explanation: Despite its name, NaN is of type 'number'.typeofnull;// -> 'object'// Explanation: Null is considered an object in JavaScript, although it is a primitive value.
7. Miscellaneous
{}+[];// -> 0[]+{};// -> '[object Object]'// Explanation: The order of operations and type coercion produce different results.[10,1,3].sort();// -> [1, 10, 3]// Explanation: Default sorting converts elements to strings, sorting them lexicographically.letf=()=>{};f();// -> undefined// Explanation: Arrow function with empty block returns undefined.letf=function(){returnarguments;};f("a");// -> { '0': 'a' }// Explanation: Regular function captures arguments.letf=()=>arguments;f("a");// -> ReferenceError: arguments is not defined// Explanation: Arrow function does not capture arguments.(()=>{try{return2;}finally{return3;}})();// -> 3// Explanation: finally block overrides the return statement.newclassFextends(String,Array){}();// -> F []// Explanation: Extends clause uses the last argument, so class extends Array.letx,{x:y=1}={x};y;// -> 1// Explanation: Destructuring with default value when x is undefined.[...[..."..."]].length;// -> 3// Explanation: Spreading a string spreads its characters into an array.foo:{console.log("first");breakfoo;console.log("second");}// Explanation: Labeled block with break statement.typeofnewclass{class(){}}();// -> 'object'// Explanation: Keyword can be used as method name.
📚 Other resources
qit.tools - JavaScript's Gotchas (WTF JS): Unexpected Behaviors
Top comments(1)
Subscribe
For further actions, you may consider blocking this person and/orreporting abuse