4

I still find the with keyword a bit...enigmatic.

Briefly, with behaves like this:

with (obj) {
    // do stuff
}

This adds obj to the head of the scope chain and then executes the with-block. When the block is finished it removes obj from the head of the scope chain.

According to MDC, this allows you to do stuff like

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

So I can reference properties of Math -- like PI -- directly, without saying Math.PI. Which is fine, but kind of useless.

Can anyone provide an example of an interesting usage of with?

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
ntownsend
  • 7,462
  • 9
  • 38
  • 35
  • possible duplicate of [Are there legitimate uses for JavaScript's "with" statement?](http://stackoverflow.com/questions/61552/are-there-legitimate-uses-for-javascripts-with-statement) – Shog9 Aug 18 '10 at 00:07

6 Answers6

5

An alternative to the standard closure solution using functions inside of a for loop:

<a  href="#">blah</a><br>
<a  href="#">blah</a><br>
<a  href="#">foo</a><br>
<script>
    (function() {
    var anchors = document.getElementsByTagName('a');
        for ( var i = anchors.length; i--; ) {
            var link = anchors[i];
            with ({ number: i }) {
                link.onclick = function() {
                    alert(number);
                };
            }
        }
    })();
</script>

Credit to nlogax for providing a solution which I pretty much ripped off: Javascript infamous Loop issue?

Here's the standard solution:

<script>
    (function() {
    var anchors = document.getElementsByTagName('a');
    for ( var i = anchors.length; i--; ) {
        var link = anchors[i];
        (function(i) {
            link.onclick = function() {
                alert(i)
            }
        })(i);
    }
    })();
</script>
Community
  • 1
  • 1
meder omuraliev
  • 183,342
  • 71
  • 393
  • 434
4

It should be said here that the with statement in JavaScript is widely deprecated.

See Douglas Crockford's With Statement Considered Harmful.

I can't say it any better than he did (seriously, follow the link), but in short if you do this:

with (mySuperLongObjectReferenceThatIHateTyping) {
  propertyAlpha = 'a';
  propertyBeta = 2;
  propertyGamma = false;
}

You can't know by looking at that code if you're assigning values to properties of the mySuperLongObjectReferenceThatIHateTyping object or of the global object (window).

Crockford recommends this:

var o = mySuperLongObjectReferenceThatIHateTyping;
o.propertyAlpha = 'a';
o.propertyBeta = 2;
o.propertyGamma = false;

Which is unambiguous. Or you could even use a function so you have scope and don't create another global variable:

(function(o) {
  o.propertyAlpha = 'a';
  o.propertyBeta = 2;
  o.propertyGamma = false;
})(mySuperLongObjectReferenceThatIHateTyping);
Neall
  • 26,428
  • 5
  • 49
  • 48
  • 2
    The money quote: "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." – artlung Nov 05 '09 at 00:22
3

John Resig's javascript microtemplating shows some interesting use for with.

fforw
  • 5,391
  • 1
  • 18
  • 17
2

I regularly use it to add multiple CSS properties to a style object, eg

with(document.body.style) {
    color = 'green';
    background = 'red';
}

Also, I used it at least once to assign the properties of an object to local variables without having to store a reference to the object itself.

It's also an alternative to closures when you want to take a 'snapshot' of the value of a variable:

var foo = [];
for(var i = 10; i--;)
    with({ i : i }) foo[i] = function() { document.writeln(i); };

// prints 0..9
for(var i = 0; i < foo.length; ++i)
    foo[i]();

Keep in mind that with can seriously impact performance as the prototype chain of the object you added to the lexical environment has to be checked first when resolving any variable name.

Christoph
  • 164,997
  • 36
  • 182
  • 240
1

I originally answered this on Apr 14, 2012.

Update Aug. 2022: I no longer try to use with. And the crap I wrote here about some complex style of doing class-like objects, I now judge inappropriate.

Jack Waugh
  • 11
  • 2
1

The with statement in JS is like the with statement in say VB.net. It is simply a way to avoid repetition with properties / methods of an object.

For instance, assume a label control is being modified based on an event / action. That label control has properties such as FontColor, CSSClass, Visibility etc.

Instead of the programmer writing:

myLabel.FontColor=Color.Blue
myLabel.CSSClass="SomeCSSClass"
myLabel.Visiblity=True
myLabel.Text = "Hello World"

We can shorten that to:

With myLabel
  .Text = "Hello World"
  .FontColor = Color.Blue
  .CssClass="SomeCSSClass"
  .Visibility=True
End With
JonH
  • 32,732
  • 12
  • 87
  • 145