JavaScript’s with statement was intended to provide a shorthand for writing recurring accesses to objects. So instead of writing
ooo.eee.oo.ah_ah.ting.tang.walla.walla.bing = true; ooo.eee.oo.ah_ah.ting.tang.walla.walla.bang = true;
You can write
with (ooo.eee.oo.ah_ah.ting.tang.walla.walla) {
bing = true;
bang = true;
}
That looks a lot nicer. Except for one thing. There is no way that you can tell by looking at the code which bing and bang will get modifed. Will ooo.eee.oo.ah_ah.ting.tang.walla.walla be modified? Or will the global variables bing and bang get clobbered? It is impossible to know for sure.
The with statement adds the members of an object to the current scope. Only if there is a bing in ooo.eee.oo.ah_ah.ting.tang.walla.walla will ooo.eee.oo.ah_ah.ting.tang.walla.walla.bing be accessed.
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.
Fortunately, JavaScript also provides a better alternative. We can simply define a var.
var o = ooo.eee.oo.ah_ah.ting.tang.walla.walla; o.bing = true; o.bang = true;
Now there is no ambiguity. We can have confidence that it is ooo.eee.oo.ah_ah.ting.tang.walla.walla.bing and ooo.eee.oo.ah_ah.ting.tang.walla.walla.bang that are being set, and not some hapless variables.
April 21, 2010 at 7:21 am
Hello Crockford I love your speeches an views on javascript but I have looked into the ECMAScript standard and I belive that the with statement can be used but has to be used responsably. It can be dangerous but it can also be vary powerfull. one of the best example uses for the with statement can be found in Firebug. the with statement is safe enough that i don’t think it should be removed from ECMAScript
May 12, 2010 at 7:09 am
the best whey to shrink object refrences that i have found is something like this i have been doing this for quite a while
(function($){
$.bing = true;
$.bang = true;
}(ooo.eee.oo.ah_ah.ting.tang.walla.walla));
this is realy useful for doing math heavy algorithoms
(function($,x){
return $.cos($.asin(x));
}(Math,0.5));
May 12, 2010 at 7:24 am
You could also write that as
Math.cos(Math.asin(0.5))
which would be smaller, faster, and more legible.
July 30, 2010 at 5:43 am
why not just prevent any variable assignment within the with block. For example with(object){
someFunction();
myArray[10]=someProperty;
} works but you can’t do with(object){
x=someProperty
}
August 17, 2010 at 6:03 pm
This is all very pretty, and nice to know, and should be accepted as norm of regular code. However, DSLs are very useful, are not normal code in most languages (method chaining technique is famous for breaking Law of Demeter), as Martin Fowler says on his introduction to the topic: As you can see methods defined for Method Chaining violate basic rules for API design. A DSL (with stripped commas for a bit less of noise) that is only possible with the ‘with’ statement (or instance_eval in Ruby):
Remember:
Rebels learn the rules better than the rule-makers do. Rebels learn where the holes are, where the rules can be breached. Become an expert at the rules. Then break them with creativity and style.
-Kristine Kathryn Rusch
September 6, 2010 at 2:13 am
By the same reasoning…
var test='global';
function doTest(){
var test='function';
return test;
}
alert(doTest());
alert(test);
September 13, 2010 at 2:33 pm
Okay, I think we can all agree that, when talking about the ooo.eee.oo.ah_ah.ting.tang.walla.walla object, it is NEVER a good idea–due to certain nebulous security issues inherent in the JavaScript engine–to set bing AND bang to true at the same time!
September 14, 2010 at 7:19 am
“You could also write that as
Math.cos(Math.asin(0.5))
which would be smaller, faster, and more legible.”
Or you could write it as
with(Math) cos(asin(0.5));
Which is even smaller, much more legible, and importantly, far more similar to what real mathematical equations look like.
I also doubt very much that this is in any significant way slower than referencing ‘Math’ multiple times.
It is probably not worth the trouble to use ‘with’ for a mere 2 function calls, but if you are doing much more, it seems like a great way to make your code more legible. And in the case of ‘with(Math)’ there is absolutely no ambiguity about what object sin/cos/floor/ceil/pow etc. come from.
December 27, 2010 at 4:52 pm
[...] way only works if you avoid using the javascript function eval() and statement with, both of which are vilified for their blocking of javascript minifying, among other issues.) A real-world example of [...]
January 25, 2011 at 10:27 pm
(function(){
with(this){ // ‘this’ is one of scope chains
bing = true;
bang = true;
}
}).apply(ooo.eee.oo.ah_ah.ting.tang.walla.walla);
If ‘bing’ is member of walla, then walla.bing will be setted.
If ‘bing’ is not member of walla, then bing will be global variant.
February 17, 2011 at 1:40 am
[...] geek, loves Mac a… To add, this article and also it's comments highlight few points. http://www.yuiblog.com/blog/2006… Another point to add, I think it also hurts performance because it adds one more level of scope [...]
February 22, 2011 at 11:59 am
The point is not that -with- is useless. The point is that it is, unfortunately, dangerous. And that it is, fortunately, unnecessary. Features that are both dangerous and unnecessary should to be used at all.
March 4, 2011 at 7:16 am
This might be a solution to the problem if anyone really needs to use with():
var obj = {a : ‘foo’, b : ‘bar’}, b = ‘brain’;
// add _ prefix to object elements
function _(obj)
{
for (var prop in obj)
this['_'+prop] = obj[prop];
}
// write obj.a and obj.b
with (obj)
{
document.write(a);
document.write(b);
}
document.write(”);
// write obj.a and global b
with (new _(obj))
{
document.write(_a);
document.write(b);
}
// original object still remains
for (var prop in obj)
document.write(”+prop+’ = ‘+obj[prop]);
April 5, 2011 at 1:30 am
[...] von Scripts können in einen Strict Mode versetzt werden, in dem einige defekte JS-Altlasten (z.B. with(){}) nicht mehr verwendet werden können und der an einigen Stellen die Regeln von JavaScript so [...]