views:

228

answers:

6

I seem to remember there is a problem with WITH. I don’t miss it; I prefer each line of my code to stand on its own.

I started wondering about this when I learned (at SO) that people consider chaining one of their favorite features of jQuery. JavaScript’s WITH and jQuery’s chaining is, basically, the same feature, right?

+3  A: 

With and chaining aren't quite the same. With affects scope, while chaining doesn't. Consider:

a.b.c = foo;

or:

with(a.b) { c = foo; }

In the second case, you've got no idea if c exists outside the with block, so if it's possible that you're just clobbering something another part of the program is relying on.

+5  A: 

No, they aren't the same thing...

With is a shorthand to reference a class's members without the need to fully qualify their names.

with o 
{
   x = y;   // where x is a member of o. But how can you tell for sure?
}

Read what Douglas Crockford has to say about With. He encourages avoiding it--says its error prone and ambiguous. I agree with him.

jQuery chaining is a way to implement a fluent interface that allows you to pipe the result fro one method directly into another method. That is the output of a given method serves as input into the next. jQuery chaining can indeed look like with if you use lots of whitespace. The example below is from John Resig shows this.

jQuery("div").hide("slow", function(){
  jQuery(this)
    .addClass("done")
    .find("span")
      .addClass("done")
    .end()
    .show("slow", function(){
      jQuery(this).removeClass("done");
    });
});

Read about jQuery chaining here and here

rp
+2  A: 

You should read with Statement Considered Harmful for a good explanation as to why you should avoid with.

No, with is not the same as chaining:

JavaScript’s with statement was intended to provide a shorthand for writing recurring accesses to objects.

Grant Wagner
A: 

Or you can reference from Mozilla here get more information.

The following is a fragment of the article

'with' makes it hard for a human reader or JavaScript compiler to decide whether an unqualified name will be found along the scope chain, and if so, in which object. So given this example:

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

only when f is called is x either found or not, and if found, either in o or (if no such property exists) in f's activation object, where x names the first formal argument. If you forget to define x in the object you pass as the second argument, or if there's some similar bug or confusion, you won't get an error -- just unexpected results.

Gordian Yuan
+2  A: 

fwiw, I strongly disagree with crockford and the whole anti-with movement. Yes, I enjoy flogging deceased equestrians too.

The point where I agree with the anti's is that with should never be used as a crutch for object creation/assignment which in effect means never used directly:

BAD

with(a.b)
{
  c = x;
}

GOOD

with(a)
{
  b.c = x;
}

I believe the second form actually increases readability because it both indicates a block (the with itself) and removes whitespace (less text = less brainache) without recourse to redundant declarations/assignments. My argument is that with is only dangerous when you don't know what you're doing, and my follow on from that is if you don't know what you're doing you shouldn't be doing it. As I said, I realise I'm against the grain here.

annakata
"My argument is that with is only dangerous when you don't know what you're doing"But isn't that the point that Crockford makes... With makes it easy to do what you think you aren't doing! I like the explicitness that avoiding with provides. I've also got a sweet spot for deceased equestrian floggers, too.
rp
I disagree with the philosophy that it makes it easy to make mistakes - so does C++ and you'd have a hard time fighting that one. Poor use of with is what causes the problems, using it in a non-risky way affords more readable code. (imho)
annakata
There are cases where 'with' makes sense, for example when reading values from an object. However, IIRC I heard that Google Crome is slower when using 'with', and they recommend that you assign the object to a new variable and use that variable instead. I think it had something to do with caching. In other languages, like Pascal, 'with' can speed things up since the compiler can optimize the code, but that is not the case in javascript.
some
+1  A: 

I think the question has been answered above, just wanted to add my two cents on the topic of 'with.' The example almost all of you bring up are ambigious class and variable names, which with with or without with are hard to maintain and understand. If you name your variables, classes, objects with some kind of meaning with can be golden.

var car = {
           wheels: {radius: 5, rim: 'gold', shape: 'circle'},
           body: {color: 'black', windows: 'tinted'}
           };

and Now:

with (car){
    wheels.shape = square;
    body.color = blue;
}

Point being, with can be powerful and save a lot of time for the programmer after you. It works well only if you use it correctly and already have a habit of verbose naming of variables and sufficient commenting. Furthermore, someone said that if you do:

with(a){
    x = 3;
}

that somehow a variable that is not a member of the class will somehow gets overridden. Correct me if I am wrong but if there is a global variable x and a property a.x, in the with block, only the a.x get's overridden since that is the current scope.

Dmitri Farkov
The argument the anti's make about your "x" example is that reading it you don't know whther x is global or not, and the behaviour may not be as expected if a does not have an x member.
annakata
I just think anyone with knowledge of how *with* works, would be able to figure out. Especially if variable names are verbose.
Dmitri Farkov
yeah, I'm not entirely unsympathetic :)
annakata
You're absolutely correct, only the a.x gets overridden. It's still ambiguous, though. In your more verbose example, you may well have a "wheels" variable outside the "with" scope. If you've got an undiagnosed bug in that code, it's difficult for someone coming along later to tell what you actually meant. "With" then imposes a higher comment burden than code without it.I'm taking a leaf out of Python's book here: explicit is better than implicit.
I understand the viewpoint, it's just I believe that when debugging one will not overlook looking up a couple of lines and seeing with. I guess to each their own. I do want to say I see both viewpoints, I am just more sympathetic to *with*.
Dmitri Farkov