Explain Codes LogoExplain Codes Logo

Are there legitimate uses for JavaScript's "with" statement?

javascript
javascript-best-practices
scope-management
modern-javascript
Nikita BarsukovbyNikita Barsukov·Jan 24, 2025
TLDR

Yes, the with statement in JavaScript can be employed to simplify multiple property access on an object, but often at the expense of clarity. Best practice recommends avoiding with due to potential confusion concerning scope and to maintain code quality. A preferred, modern method is object destructuring, which is explicit and clear:

/* Instead of using 'with', Let's go on a car ride, shall we? */ with(car) { console.log(`Driving a ${make} ${model} from ${year}`); } // Using the 21st-century friendly object destructuring! let { make, model, year } = car; console.log(`Driving a ${make} ${model} from ${year}`); /* Phew! Now we know for sure where make, model, year are coming from! */

As seen above, object destructuring is a highly favorable practice which provides conciseness without compromising code readability and robustness.

Chasing brevity with "with"

The with statement in JavaScript can be both a blessing and a curse. It provides a sweet little shortcut for accessing object properties but can backfire by sacrificing code readability and maintainability. Some may find it beneficial in a scenario like DOM manipulation:

/* Hmmm… this seems handy for DOM manipulation. Nope! It's a trap! */ with(document.forms[0]) { with(elements) { userName.style.backgroundColor = '#fafafa'; password.style.backgroundColor = '#fafafa'; } }

Though it may seem handy to reduce the repetition of document.forms[0].elements, it makes your code hard to track and often causes variable origin confusion.

Replicating block scoping using "with"

with statement does an uncanny mimicry of block scope by simulating let even before ES6 came onto the scene.

/* Pre-ES6 method of 'creating' block scope. Want a time-travel ticket back to ES3 anyone? */ with({x: 1}) { console.log(x); // Outputs: 1 } /* Well, that worked… but it's like using a chainsaw to trim your hedges. Overkill, and dangerous! */

While this might seem savvy, it can induce unnecessary ambiguity in larger codebases making it challenging to discern the origin of the variables.

The lure and lore of markup building

A very niche application for with might be constructing markup or handling repetitive object references:

// This is compacting references to create SVG elements with(document.createElementNS(svgNS, 'svg')) { setAttribute('width', 150); setAttribute('height', 150); /* More attributes and operations Crafting SVGs? How 'artful'...! */ }

This usage can make verbose API calls seem less daunting but can severely impact code readability and might bring about optimization issues.

Planning readability with "with"

with statement can, at first glance, provide a cleaner look in templating situations:

/* Tempting use within a templating rendering function Hold on, let's not jump the gun! */ with(templateContext) { // Accessing context properties without repetition output = `<h1>${title}</h1><p>${content}</p>`; }

While convenient, this may seem like a Pandora's box of potential scope problems. Just remember, not all that glitters is gold!

Why modern JavaScript is reluctant to use "with"

In modern JavaScript standards, employing with is generally discouraged or completely banned in strict mode. Dispensing with is beneficial due to the scope for silent errors and the cognitive challenge it brings:

  • Silent errors: Undeclared variables inside a with block default to properties on the given object, potentially masking typos and undeclared variables.
  • Cognitive load: Tracking whether a variable is local, part of the with object, or a global variable adds to the cognitive load, making maintenance harder.

Better alternatives to "with"

As a responsible and modern developer, have a look at these alternatives for effective JavaScript scope management:

  • Object destructuring: Extract multiple properties using a single statement — all explicit and clear.
  • Property shorthands: Within objects, use { x } instead of { x: x }, offering cognitive ease and clarity.
  • Template literals: A fantastic way of substituting values in strings is by using ES6 template literals and chucking out the old manual string concatenation.