DEV Community

Michael Z
Michael Z

Posted on • Originally published at michaelzanggl.com

4 1

Namespaces are just fine - No need to destructure every object in JavaScript

An increasingly common practice in JavaScript is destructuring. This is great to get rid of otherwise generic terms like in the following examples.

Destructuring objects:

/*❌*/ const results = await fetch('users')
/*❌*/ results.users
/*✔️*/ const { users } = await fetch('users')
Enter fullscreen mode Exit fullscreen mode

Destructuring arrays:

/*❌*/ const results = await validate(request)
/*❌*/ if (!results[0]) throw results[1]
/*✔️*/ const [isSuccessful, error] = await validate(request)
/*✔️*/ if (!isSuccessful) throw error
Enter fullscreen mode Exit fullscreen mode

These are very good use-cases for destructuring!

But then there is the other side of the coin:

const { user: { city }} = results
Enter fullscreen mode Exit fullscreen mode

The variable “city” had a perfect home with the namespace “user”. It’s very clear that “user.city” is the city belonging to the user. With the nested destructuring technique, you lose these benefits.


This overdestructuring can also lead to name clashes, which would require renaming the variable:

const { city } = location
const { user: { city: userCity }} = results
Enter fullscreen mode Exit fullscreen mode

“userCity” vs. “user.city”. Is this difference worth the added complexity and loss of intent?

Compare these two code statements that could follow the above example:

/*❌*/ if (city === userCity) {}
/*✔️*/ if (location.city === user.city) {}
Enter fullscreen mode Exit fullscreen mode

In multi-line statements, over-destructuring can also confuse the reader as to which side of the assignment the reader is currently on (left side or right side):

const {
  user: {
    city: userCity
  },
  location: {
    city: locationCity
  }
  ...rest
} = {
  ...cache,
  user: await getUser()
  date: now()
}
Enter fullscreen mode Exit fullscreen mode

Not enough? How about some inlined TypeScript types to mix things up:

const {
  user: {
    city: userCity
  },
  location: {
    city: locationCity
  }
  ...rest
} = {
  ...cache,
  user: await getUser()
  date: now()
} : {
  user: {
    id: string;
    city: string
  }
  date: number,
  location: {
    id: string;
    city: string;
  }
}
Enter fullscreen mode Exit fullscreen mode

Namespaces are just fine. In fact, they are very helpful in communicating where a variable belongs to. And best of all, you get all of it out of the box.


This was an excerpt from my e-book Intent-Driven Development which will teach you how to simplify the day-to-day code you run into and the balance between over- and under-engineering. Get it over at https://michaelzanggl.com/intent.

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay