views:

234

answers:

8

I saw JavaScript code which begins with with. That's a bit confusing. What does it do and how can it be used correctly?

with (sObj) return options[selectedIndex].value;
+15  A: 

It adds to the scope of the statements contained in the block:

return sObj.options[selectedIndex].value;

can become:

with (sObj)
    return options[selectedIndex].value;

In your case, it doens't do a whole lot...but consider the following:

var a, x, y;
var r = 10;
a = Math.PI * r * r;
x = r * Math.cos(PI);
y = r * Math.sin(PI /2);

Becomes:

var a, x, y;
var r = 10;
with (Math) {
  a = PI * r * r;
  x = r * cos(PI);
  y = r * sin(PI / 2);
}

...saves a couple of keystrokes. The Mozilla documentation actually does a pretty good job of explaining things in a little more detail (along with pros and cons of using it):

with - Mozilla Developer Center

Justin Niessner
Lame usage, just like in VBA. In Python with can take care of cleaning up a disposable object. In C# it is called using.
Hamish Grubijan
+1 - Hey Justin - Nice explanation
Mark Brittingham
@Mark - Thanks. Looks like I should've included the 'suggest not to use this' clause though.
Justin Niessner
+1 Thanks Justin for answering the question. It's easy to be PC and just say don't use it - but if we make the effort to understand and try out features for ourselves, we can make informed decisions
plodder
A: 

I would recommend NOT using this because of performance issues, but what the above means is:

for the object sObj (here presumably a select element), all children and properties referenced on this one (or between following curly braces) treat that as their parent scope.

Robusto
A: 

It isn't a function (as was indicated in the question title before it was edited) but a statement. It may make more sense if the code sample is formatted like so:

with (sObj){
    return options[selectedIndex].value;
}

Regarding what it does (Source)

The with statement establishes the default object for a set of statements. JavaScript looks up any unqualified names within the set of statements to determine if the names are properties of the default object. If an unqualified name matches a property, then the property is used in the statement; otherwise, a local or global variable is used.

Which means that in the code sample, it is first checked if options is a property of sObj. If it is then options refers to sObj.options, otherwise it checks other scopes for a variable defined by the name options

The downside of using a with statement is that it is impossible to know from just glancing at the code what gets accessed. There are other better alternatives as shown in this article

Yacoby
Whilst the rest of your answer is correct, formatting has relatively little to do with it.
belugabob
@belugabob Please *read* the answer rather than guessing as to its content. I never mentioned formatting having any relevance to the `with` statement at all. I said it makes more *sense* if it is formatted using braces as it makes it look less like a function call and more like a statement.
Yacoby
@belugabob I have also rearranged the word order to make it harder to misunderstand.
Yacoby
Yes - it makes more sense now.
belugabob
+1  A: 

In that with block you dont have to type:

sObj.options[selectedIndex].value

but you can just use:

options[selectedIndex].value
Fabian
+1  A: 

Its the equivalent of

return sObj.options[selectedIndex].value;

With lets you issue a block of statements in the context of a particular object. Therefore all of the statements in the with block are taken to be members of the object in parenthesis.

This can make code more readable at times, but it also can lead to ambiguity, since the variable references can either be with sObj or global.

legitimate uses for javascript's "with" statement :D

CrazyJugglerDrummer
+9  A: 

the with statement is pure syntactical sugar, but it also can cause some nasty bugs.

See with Statement Considered Harmful for clarification:

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.

chills42
++ for mentioning the disadvantages of 'with'
CrazyJugglerDrummer
+1  A: 

Your example could be rewritten as...

return sObj.options[selectedIndex].value;

...as the 'with' statement places all related statements in the scope of the supplied object. In this case, it's pretty pointless but, if you were doing lots of operations on 'sObj', then it saves a lot of typing.

Totally ficticious example..

with (sObj) 
{
   if(options[selectedIndex].value < 10){
       options[selectedIndex].value++;
       total+ = options[selectedIndex].value;
   }
}

But, having said that, it's often the case that saving typing can be achieved in better ways.

belugabob