Igor's Techno Club

Meme Review: Thanks For Inventing JavaScript

2024-12-17 21

Let's break down each example from the meme in detail:

typeof NaN

Output: "number"

In JavaScript, NaN is actually a special numeric value representing an invalid or unrepresentable number. NaN is part of the IEEE-754 floating-point number specification used by JavaScript.

9999999999999999

Output: 10000000000000000

This is a perfect example of JavaScript's number precision limitations. JavaScript uses 64-bit floating-point numbers (IEEE-754), which can only precisely represent integers up to 2^53 - 1 which is 9007199254740991. Beyond that, number considered as unsafe and in some examples incorrect rounding may occur.

If you want to verify whether a number is safe, you can use the isSafeInteger method: Number.isSafeInteger(9007199254740992).

0.5+0.1==0.6

Output: true

This comparison works correctly because these particular decimal numbers can be precisely represented in binary floating-point. It's one of the "well-behaved" floating-point calculations.

0.1+0.2==0.3

Output: false

This is perhaps one of the most famous JavaScript quirks. Due to how floating-point numbers are stored in binary, 0.1 and 0.2 cannot be precisely represented. When added, they actually result in 0.30000000000000004, which is not exactly equal to 0.3.

Math.max()

Output: -Infinity

When called with no arguments, Math.max() returns -Infinity. This makes sense from a mathematical perspective: any other number you compare with -Infinity will be greater, making it a suitable initial value for finding a maximum.

Math.min()

Output: Infinity

The counterpart to Math.max(), Math.min() returns Infinity when called with no arguments. Any other number compared to Infinity will be smaller.

[]+[]

Output: ""

When you add two arrays, JavaScript first converts them to strings. An empty array converts to an empty string, so you're effectively concatenating two empty strings.

You can check formalized version of the coercion algorithm here

[]+{}

Output: "[object Object]"

Here, the empty array converts to an empty string, and the empty object converts to the string "[object Object]". These are then concatenated: Screenshot 2024-12-17 at 23

{}+[]

Output: 0

This one is about how the expression is being parsed to AST. When {} appears at the start of a line/statement, JavaScript's parser sees this as two separate entities:

The first {} is interpreted as an empty code block (not an object), and +[](unary plus operation on an array) converts the empty array to a number, which is 0. The code block doesn't result in a value, so 0 is the output.

You can check formalized version of the unary coercion algorithm here

true+true+true===3

Output: true

In numeric contexts, true converts to 1 and false to 0. Therefore, true + true + true is evaluated as 1 + 1 + 1, making this expression equivalent to 1+1+1===3.

true==1

Output: true

When using loose equality (==), JavaScript performs type coercion. true gets converted to 1, making this comparison true.

See rules of == conversion in details here

true===1

Output: false

With strict equality (===), no type coercion occurs. Since true is a boolean and 1 is a number, they're not the same type, so the comparison is false.

(!+[]+[]+![]).length

Output: 9

This is a complex example of type coercion:

9+"1"

Output: "91"

When adding a number to a string, JavaScript converts the number to a string and performs concatenation.

91-"1"

Output: 90

The minus operator - only has one purpose - subtraction. It always converts its operands to numbers, so "1" becomes 1, and 91-1 equals 90.

[]==0

Output: true

Through a series of type coercions:

true-true

Output: 0

Both true values are converted to 1, so this becomes 1-1=0.

Rules Of + Operator

The + operator in JavaScript can perform both addition and string concatenation, depending on the types of its operands. Here's a simplified view of the coercion process, as specified by the ECMAScript specification:

Primitive Conversion:

The first step is converting both operands to primitive values:

Objects (including Arrays):

When an object (or Array, as it's technically an 'object' at its root) is involved, JavaScript:

toString():

Arrays don't have a valueOf() method that returns a primitive value, so they proceed directly to calling toString()

Type Check and Operation: After primitive conversion:

Rules of unary + Operator Coercion

Step 1: Unary Plus Operation

The + operator in front of [] is a unary plus operator, which attempts to convert its operand to a number.

Step 2: Array to Primitive Conversion

When converting an array to a primitive for numeric operations:

  1. First, JavaScript tries to call valueOf() on the array
    • For arrays, valueOf() just returns the array itself, which is not primitive
  2. Since valueOf() didn't give a primitive, it calls toString()
    • [].toString() converts an empty array to an empty string ""

Step 3: String to Number Conversion

Now that we have an empty string "", the unary plus converts it to a number:

Rules Of == Coercion

The == (loose equality) coercion in JavaScript follows a specific algorithm defined in the ECMAScript specification. Here's the simplified flow:

Basic Rules of == Coercion

  1. If types are the same:

    null == null        // true
    undefined == undefined  // true
    true == true        // true
    5 == 5              // true
    "foo" == "foo"      // true
    
  2. If comparing null and undefined:

    null == undefined   // true
    undefined == null   // true
    
  3. If one operand is a number and one is a string:

    • Convert string to number
    5 == "5"           // true (converts "5" to 5)
    "5" == 5           // true (converts "5" to 5)
    
  4. If one operand is boolean:

    • Convert boolean to number (true → 1, false → 0)
    true == 1          // true (converts true to 1)
    false == 0         // true (converts false to 0)
    
  5. If one operand is object and other is primitive:

    • Convert object to primitive using valueOf() or toString()
    [1,2] == "1,2"     // true (array converts to "1,2" string)
    [] == ""           // true (empty array converts to empty string)
    [0] == 0           // true ([0] → "0" → 0)
    

#meme_review #webdev