DEV Community

Discussion on: The forgotten `with` statement — and why you shouldn't use it

Collapse
 
baso53 profile image
Sebastijan Grabar

This seems like a very nice feature in some places. I don't think the arguments (actually, it's just a single argument) against it are justified.

You could have any of these problems in a for loop for example. Does that mean we should abandon the for loop because it COULD lead to readability issues? No. Good tooling prevents you from this kind of problems.

Kotlin seems to do just fine with the "with" statement.

Collapse
 
lioness100 profile image
Lioness100 • Edited

Thanks for the input! Could you elaborate on how you would get the same problem the with statement introduces in a loop, and what "good tooling" can completely prevent it?

P.S. If I'm reading the docs correctly, Kotlin's with has completely different functionality wise than Javascript's.

Collapse
 
baso53 profile image
Sebastijan Grabar
const foo = 'bar';
with ({ foo: 'baz' }) {
  console.log(foo);
}
Enter fullscreen mode Exit fullscreen mode
const foo = 'bar';
for(let foo = 0; foo<5; foo++) {
  console.log(foo); // which foo will be printed?
}

Enter fullscreen mode Exit fullscreen mode

You have the exact same problem here. Yet, no one is stating that you shouldn't use the for loop.

All I'm saying is, not using something just because someone said so is sometimes counter-productive. Frankly, this is the first time I've heard of this feature and I'm a little saddened that it's labeled as discouraged.

When comparing to Koltin, they are very similar. The difference is that in Kotlin, this is going to be only the object passed to the with statement, while in JS, this will (effectively) be set to the enclosing this + the object passed to the with statement.

This is the kind of stuff a linter could easily warn you of.

Thread Thread
 
lioness100 profile image
Lioness100

I agree that the "Which is logged?" question isn't particularly useful to determine whether you should us ethe statement or not, since, when creating multiple scopes, you will always run that risk.

const foo = 'bar';
function test() {
  const foo = 'baz';
  console.log(foo); // here it is again
}
Enter fullscreen mode Exit fullscreen mode

However, the much bigger fish I was talking about is when you accidentally reference something you didn't even know existed in the object you use. This problem is not shared with loops since you explicitly write out all variable names, so I don't think your comparison applies.

And what can a linter do? In the example I showed in the post, the linter wouldn't find anything wrong. The only thing linters do is tell you not to use with.