🧐 JavaScript Shenanigans: Time Travel with Destructuring

oculus42

Samuel Rouse

Posted on July 31, 2024

🧐 JavaScript Shenanigans: Time Travel with Destructuring

Did you know you can time travel with variable assignment in JavaScript? Here's some silly JavaScript trivia for your day.

Multiple Assignment

You probably know about multiple assignment in JavaScript. Hopefully you know that it's not recommended because it can be hard to see when it's not in a tiny example and is a good way to introduce bugs if you assign one object to two variables.

let a, b;

// Set two things at once
a = b = 1;

a; // 1
b; // 1
Enter fullscreen mode Exit fullscreen mode

If you do use this, be careful! It's possible to accidentally create a variable in the global scope.

// a is local, b is global unless declared beforehand!
const a = b = 1;

a;            // 1
globalThis.b; // 1
Enter fullscreen mode Exit fullscreen mode

But multiple assignment is possible, and it works with destructuring, too! Multiple assignment returns the variable, so each destructuring above gets the full array.

let a, b;

// πŸ”Ž Looks pretty strange
[, ...a] = [b] = [ 0, 1, 2 ];

a; // [ 1, 2 ]
b; // 0
Enter fullscreen mode Exit fullscreen mode

But what about the time travel? We're getting there...

Default Values

With destructuring you can also set default values.

const [ a, b, c, d = '🍊' ] = [ 0, 1, 2 ]; 

a; // 0
b; // 1
c; // 2
d; // '🍊'
Enter fullscreen mode Exit fullscreen mode

And you can do this with multiple assignment.

let a, b;

// Defaults for missing values
[a = 'πŸ‡'] = [b = '🍐'] = [];

a; // 'πŸ‡'
b; // '🍐'
Enter fullscreen mode Exit fullscreen mode

But what about time travel?!

Time Travel

Let's see it in action, first.

let first, second, vegetable, fruit;

// πŸͺ„⏱️ Time Travel!
[ first, vegetable = fruit ] = [ second, fruit = 'πŸ…' ] = ['πŸ₯¦'];

first;  // 'πŸ₯¦'
second; // 'πŸ₯¦'
vegetable; // 'πŸ…'
fruit;     // 'πŸ…'
Enter fullscreen mode Exit fullscreen mode

vegetable shows up first on the line, but manages to access the value assigned to fruit which is assigned later in the line!

Time travel!

What's Going On Here?

Well, of course it's not really time travel. What's happening here is the difference between reading and interpretation. We read this code left-to-right, but JavaScript assignment happens right-to-left. The "second" destructuring in reading order happens first. If we break this into code is roughly equivalent.

let first, second, vegetable, fruit;

// Multiple assignment passes the original value.
// Simulate that with an interim assignmentResult inside a block.
// This block scope makes the temporary variable inaccessible.
{
  const assignmentResult = [ second, fruit = 'πŸ…' ] = ['πŸ₯¦'];

  // fruit was assigned a value by the time this code is run
  [ first, vegetable = fruit ] = assignmentResult;
}

first;  // 'πŸ₯¦'
second; // 'πŸ₯¦'
vegetable; // 'πŸ…'
fruit;     // 'πŸ…'
Enter fullscreen mode Exit fullscreen mode

Conclusion

So, not exactly time travel but a great way to demonstrate some of the unexpected functionality in JavaScript. Because the TC39 working group focuses on maintaining compatibility of older code, some mixing of old and new coding styles and standards can create confusing code.

Hopefully you never encounter real code like this!

πŸ’– πŸ’ͺ πŸ™… 🚩
oculus42
Samuel Rouse

Posted on July 31, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related