This content originally appeared on DEV Community and was authored by Lioness100
The with statement extends the scope chain for a statement.
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);
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 );
}
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)"
}
}
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);
}
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';
}
// ...
}
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);
Or:
const { name, lastName, age } = authors[0].ref.data[0].data;
console.log(name, lastName, age);
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.
Javascript Symbols + Classes = 💖
Lioness100 ・ Oct 11 ・ 4 min read
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
}
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 ✌
This content originally appeared on DEV Community and was authored by Lioness100
Lioness100 | Sciencx (2021-10-12T22:52:00+00:00) The forgotten `with` statement — and why you shouldn’t use it. Retrieved from https://www.scien.cx/2021/10/12/the-forgotten-with-statement-and-why-you-shouldnt-use-it/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.