Any examples of a non-trivial and useful example of the 'with' keyword?
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;开发者_StackOverflow
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
?
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>
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);
John Resig's javascript microtemplating shows some interesting use for with.
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.
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
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.
精彩评论