The Date Puzzle And Hidden Properties

How can we subtract two objects from each other to find the time difference? It seems impossible, yet JavaScript has a secret.

April 25, 20263 min read3 / 5

We've seen that objects are stored by reference and comparing them only checks their memory addresses. This creates a real problem for user experience. Imagine a user accidentally double-clicks a "Submit" button. We want to check if the second click happened too soon after the first and prevent a double purchase.

The Essentials

  1. The Date Object: A built-in object that stores a timestamp of "right now."
  2. Hidden Properties: Objects can have properties that aren't visible or accessible via normal dot notation (like [[DateValue]]).
  3. The Puzzle: If time1 and time2 are both objects (references), how can we ever do time2 - time1?

The Double-Click Problem

When a user clicks "Submit," we create a timestamp using new Date(). This returns an object with a hidden property called [[DateValue]], which stores the number of milliseconds since January 1st, 1970.

Let's say 1 second passes between two clicks.

JavaScript
const time1 = new Date(); // Midnight, Jan 15, 2027 (1.8 trillion ms) const time2 = new Date(); // 1 second later (1.8 trillion + 1000 ms) if (time2 - time1 < 2000) { console.log("Accident! Too soon."); }

The Impossible Math

Wait a minute. time2 and time1 are objects. They are stored in the heap at different addresses (like 10002 and 10001). Subtracting one address from another shouldn't give us the number of milliseconds. It shouldn't even be possible.

Yet, it works. JavaScript manages to get under the hood, grab those hidden millisecond values, and perform the subtraction.

JavaScript Execution Engine
Thread of Execution
1const time1 = new Date();
2const time2 = new Date();
3const diff = time2 - time1;

Step 1:time1 points to a Date object with a hidden [[DateValue]] of 1.8 trillion.

Memory
time1ref:10001
Call Stack
Global
Bottom of Stack

The Secret: @@toPrimitive

How is this possible? It's via a hidden property called @@toPrimitive.

When JavaScript sees math being done on an object, it doesn't look at the memory position. Instead, it asks: "Do you have a way to convert yourself to a primitive?"

The Date function ensures that every object it returns has a hidden instruction set (a function) stored on this @@toPrimitive property. These instructions tell JavaScript: "When someone tries to treat me like a number, return my hidden [[DateValue]]."

The "Square Bracket" Gotcha

Before we learn how to wield this power ourselves, we need to remember how we access properties. If we have a variable month = "Jan", we can use time1[month] = true to set a property called "Jan."

The thing inside the square brackets is evaluated before it's used as a key. This is the key to metaprogramming. If we can find a way to refer to that hidden @@toPrimitive label, we can add it to our own objects.

But how do we refer to a label that we can't even write out? The answer lies in a new data type: Symbols.

Further Reading and Watching