## DEV Community

YURIIDE

Posted on • Updated on

# JavaScript's Gotchas, also known as "WTF JS"

### 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 == []; // -> false
true == ![]; // -> false
// Explanation: true converts to 1 and [] converts to 0. 1 != 0.

false == []; // -> true
false == ![]; // -> 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); // -> true
NaN === 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.

let a = [, , ,];
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(); // -> 0
Number(undefined); // -> NaN
// Explanation: Number without arguments returns 0, with undefined returns NaN.

### 6. Unexpected Typeof and Instanceof

typeof NaN; // -> 'number'
// Explanation: Despite its name, NaN is of type 'number'.

typeof null; // -> '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.

let f = () => {};
f(); // -> undefined
// Explanation: Arrow function with empty block returns undefined.

let f = function() { return arguments; };
f("a"); // -> { '0': 'a' }
// Explanation: Regular function captures arguments.

let f = () => arguments;
f("a"); // -> ReferenceError: arguments is not defined
// Explanation: Arrow function does not capture arguments.

(() => {
try {
return 2;
} finally {
return 3;
}
})(); // -> 3
// Explanation: finally block overrides the return statement.

new class F extends (String, Array) {}(); // -> F []
// Explanation: Extends clause uses the last argument, so class extends Array.

let x, { x: y = 1 } = { x };
y; // -> 1
// Explanation: Destructuring with default value when x is undefined.

[...[..."..."]].length; // -> 3

foo: {
console.log("first");
break foo;
console.log("second");
}
// Explanation: Labeled block with break statement.

typeof new class { class() {} }(); // -> 'object'
// Explanation: Keyword can be used as method name.

### ðŸ“š Other resources

qit.tools - JavaScript's Gotchas (WTF JS): Unexpected Behaviors