tags:

views:

146

answers:

4
+10  A: 

just dont use it : http://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/

azazul
+1, that was the link I was looking for
cobbal
I can't express this enough: any "with"-like syntax, like the one for JavaScript and Delphi, where you're not explicitly specifying which identifiers belong to the "scoped" object, and which one aren't, are **evil**, don't use that syntax in those languages. In particular, future changes might change the behavior of that code without warning. If that isn't a bug just waiting to happen, then I don't know what is.
Lasse V. Karlsen
+1, because it's the same link I typed in while yours was already there. Deleting mine ;-).
Abel
For instance, Visual Basic.NET got it right, http://msdn.microsoft.com/en-us/library/wc500chb(VS.80).aspx, where they force you to prefix all identifiers belonging to the scoped object with a dot.
Lasse V. Karlsen
Thanks, I thought that. Just curious to see if anyone, anywhere could justify its use for any reason :)
John McCollum
Yeah, VB (.NET and before) got it right, but they also got it wrong: if you use late-binding, your still in the same problem. And performance with `with` is slower then without (for whatever odd reason).
Abel
@John: the only justification I can find is where code becomes clearer when using it. If you find yourself in such a situation, you can use it...
Abel
@John (2): about justification, check Annie's answer: http://stackoverflow.com/questions/1931186/with-keyword-in-javascript/1931202#1931202
Abel
+1  A: 

I would avoid using it in production code because it's ambiguous but there is an alternative solution to the for-loop-closure solution by using with to mimic the let binding, here's a copy of my previous answer:

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: http://stackoverflow.com/questions/1451009/javascript-infamous-loop-problem

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>
meder
Please make sure you state what part is "ambiguous", as the JavaScript interpreter and/or compiler is never confused about what to use for the identifier. It's future changes and/or what a programmer might interpret an identifier as that is the problem.
Lasse V. Karlsen
+3  A: 

Here are some blog posts in support of the with keyword. But please read the YUI blog entry that azazul posted as well!

http://webreflection.blogspot.com/2009/12/with-worlds-most-misunderstood.html http://webreflection.blogspot.com/2009/12/with-some-good-example.html

Annie
+1, think your answer really answers the "where is it justified" question, instead of pointing at the "why shouldn't you use it".
Abel
@Abel, you're right, this answers my question nicely as well as sticking a giant caveat on there too.
John McCollum
+1  A: 

Despite advice to the contrary almost everywhere, I think that there are uses for "with". For example, I'm working on a domain model framework for Javascript, which uses the underscore character in much the same way that jQuery uses "$". This means that without "with", I have lots of underscores scattered through my code in ways that make it less readable. Here's a random line from an application using the framework:

_.People().sort(_.score(_.isa(_.Parent)),'Surname','Forename');

whereas with "with" it would look like

with (_) {
    ...

    People().sort(score(isa(Parent)),'Surname','Forename');

    ...
}

What would be really useful is a read-only version of "with".

Rich