3

Possible Duplicate:
Are there legitimate uses for JavaScript's “with” statement?

in "JavaScript the Good Parts", with is deemed to be a bad part of javascript, but look at this snippet:

var foo={foof:function(){console.log(this)}}
var fuu={fuuf:function(){console.log(this)}}
with(foo){
     console.log(this);
 with(fuu){
     console.log(this);
     foof();
     fuuf();
 }
}

Is with really that bad a practice? Can with provide fun or an advantage sometimes, who can give a example?

Community
  • 1
  • 1
island205
  • 1,730
  • 17
  • 28

3 Answers3

6

That's convenient, but it still has a fundamental problem that can get you into trouble quickly. Consider this:

var foo={foof:function(){console.log(this)}}
var fuu={fuuf:function(){console.log(this)}}
with(foo){
     console.log(this);
 with(fuu){
     console.log(this);
     foof();
     fuuf();
 }
 myProp = "blah";
}

Now what happened when we assigned to myProp?

Hard to tell.

If foo contains a property named myProp, then its value is now "blah". But if it didn't, then we just assigned "blah" to the myProp of the global object (probably window). It's easy to tell what's going on in this trivial example, but what if foo had been defined 1000 lines earlier? Or in a different file? Not so easy then.

More info and an actual answer to your question here:

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

And here:

http://www.yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/

Community
  • 1
  • 1
Wayne
  • 59,728
  • 15
  • 131
  • 126
  • 1
    this is totally the popular opinion that is also held by some people much more skilled and intelligent then me, but I really disagree. Basically, what you are describing is the 1% case. It is a much better practice to take things on a case by case basis, and ask yourself if you are writing code that is clear and readable then banning something because in extreme circumstances, you can do terrible things with it. that being said, I can't think of a case where i would use a nested with. Anyways, good description of the problem, +1 – Matt Briggs Feb 17 '11 at 03:26
  • I might agree if there weren't a safer way to accomplish nearly the same thing in most cases. Just assign your deeply nested object to a var: `var o = some.long.string.of.props; o.whatever` ... – Wayne Feb 17 '11 at 03:43
  • But, hey, I think it's perfectly fine to leave off the curly braces in one-line conditionals (and I'm tired of people telling me I'm wrong about it, too). So, what do I know? – Wayne Feb 17 '11 at 03:44
2

The trouble with with is that it is somewhat ambiguous what you are doing. For instance, your foof() function call might as well be a function defined elsewhere. It is difficult to see at a glance what is being used.

Brad
  • 159,648
  • 54
  • 349
  • 530
1

I can give an example, john resigs simple (and wildly popular) client side templating function.

<editorial>
the good parts is a phenomenal book that changes lives, but crockford is not infallable, and often will declare something that is really a matter of taste (like one line if statements) is bad with the same authority that he says genuinely horrible things are bad (like the whole implicit global/explicit local thing).
<editorial>

The issue with with is addressed on the mdc page

 function f(x, o) {
  with (o)
    print(x);
 }

Basically, the value of x is ambiguous until run time. If o has a property called x, x will be that property. If not, x will be the thing passed in. That means developers reading the code may have a hard time figuring out what x means, and more importantly, the JS interpreter will not be able to apply certain kinds of optimizations it otherwise would be able to.

<opinion>
Now personally, I find with perfectly readable, and I would never ever name variables the way they are named in the above example, so I find the readability and ambiguity arguments hogwash. As for the perf argument, as long as we aren't talking about being silly (like having half your app inside a with block), is mostly an argument for premature optimization, where you are really talking about almost immeasurable amounts of wasted time in real world scenarios. I think it is a highly situational language feature that should only really ever be used when the alternative is either significantly more, or less readable code would be the alternative.
</opinion>

Matt Briggs
  • 41,224
  • 16
  • 95
  • 126