in

The forgotten `with` statement — and why you shouldn’t use it


The with statement extends the scope chain for a statement.

MDN Web Docs

The with statement was originally implemented to reduce verbosity and when dealing with long object references. If the object is particularly expensive performance-wise, it will also save the compiler from having to parse it multiple times.

You could do this:

const name = authors[0].ref.data[0].data.name;
const lastName = authors[0].ref.data[0].data.lastName;
const age = authors[0].ref.data[0].data.age;

console.log(name, lastName, age);
Enter fullscreen mode

Exit fullscreen mode

Or, you could just do this!

with (authors[0].ref.data[0].data) {
  // every property of the given object
  // is transported to the top of the scope
  // and can be referenced directly
  console.log(name, lastName, age );
}
Enter fullscreen mode

Exit fullscreen mode

Here’s a more practical example that you might find a use for in everyday work:

with(document) {
  with(documentElement) {
    insertBefore(
      createElement("script"),
      firstChild
    )
    .text = "alert(1)"
  }
}
Enter fullscreen mode

Exit fullscreen mode

I personally only found out about this keyword a week a go; probably because it has been excluded from almost all modern code. In ES5, it’s even forbidden in strict mode 🤯



Why?

Primarily, it’s confusing and can easily lead to bugs. Consider the code below:

const foo = 'bar';
with ({ foo: 'baz' }) {
  console.log(foo);
}
Enter fullscreen mode

Exit fullscreen mode

Do you think 'bar' will be logged, or do you think 'baz' will be logged? As you can see, this can lead to readability issues. Consider another segment of code below:

// whether we should show the answer of a riddle
const hidden = true;

with (document) {
  const riddleDisplay = getElementById('riddle');
  const [question, answer] = riddleDisplay.children;

  if (hidden) {
    answer.style.display = 'none';
  }

  // ...
}
Enter fullscreen mode

Exit fullscreen mode

Pretty easy to understand, right? Nope! Actually, unbeknownst to both the reader and the writer, hidden would be referencing document.hidden.

Maybe you’re paying close attention, are well versed in the Document object, and knew this would happen. But what if you didn’t know every property of an object? Maybe it’s from an external library, or you missed as a property was assigned to it higher in the file.

If you can’t read a program and be confident that you know what it is going to do, you can’t have confidence that it is going to work correctly. For this reason, the with statement should be avoided…

– Mr. Crockford



Substitutions

Instead of using the with statement, you could assign the reference to a variable, or use array destructuring!

const author = authors[0].ref.data[0].data;
console.log(author.name, author.lastName, author.age);
Enter fullscreen mode

Exit fullscreen mode

Or:

const { name, lastName, age } = authors[0].ref.data[0].data;
console.log(name, lastName, age);
Enter fullscreen mode

Exit fullscreen mode

Simple, readable, and without any uncertain implications.



Fun Fact

In my previous blog post, I talked about static Symbol properties and how they can be combined with classes.

One property I didn’t mention is Symbol.unscopables, which specify any properties that should not be transported to the highest scope.

const foo = {
  bar: 'baz',
};

object[Symbol.unscopables] = {
  bar: true,
};

with (foo) {
  console.log(bar); // Error - bar is not defined
}
Enter fullscreen mode

Exit fullscreen mode


I hope you learned a bit about the with statement! If you have any questions, corrections, or addons, I would love to hear them. Peace ✌



Source: https://dev.to/lioness100/the-forgotten-with-statement-and-why-you-shouldnt-use-it-379c

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

GIPHY App Key not set. Please check settings

The best PCIe 4.0 SSD thumbnail

The best PCIe 4.0 SSD

A simple scholar management app that helps owners manage their scholars