The following doesn't work (although it gives no explicit error), but why not?
And... Is there really no way around it, strictly using the with statement? Forget using for / foreach.
with (object1, object2) {
attribute = value;
method();
}
edit: Sorry to make 2 questions in 1. I'll try to make it clearer:
Why the code above gives no syntax error, doesn't work but is accepted by with
?
If it's possible, how could we change multiple objects with same attribute using with
?
Hopefully the following example will be more clear on what I wanted to accomplish:
var object1 = { attribute: 3 };
var object2 = { attribute: 2, method: function() { alert('blah'); } };
var object3 = { method: function() {alert('bleh'); } };
var value = 4;
with (object1)
with (object2)
with (object3)
{
attribute = value;
method();
}
alert(object1.attribute + object2.attribute);
// resulting alerts should be, in order: blah, bleh, 8
with
This is what I originally thought you were after, since you hadn't specified what your expected results were. Just stack the with
statements:
var object1 = { attribute: 3 };
var object2 = { method: function() { alert('blah'); } };
var value = 4;
with (object1)
with (object2)
{
attribute = value;
method();
}
alert(object1.attribute);
Naturally, the object introduced by the inner-most with
will override identically-named properties in any outer scope, including those of the outer with
statements.
Standard disclaimers apply regarding performance hits and potential for errors caused by the use of with
. Note that your example shows property access prefixed by .
within the block, but this is incorrect - with
modifies scope, temporarily putting an object at the front of the resolution chain, so no prefix is necessary (or allowed).
Regarding your edit: the comma operator lets you write something that appears to pass multiple expressions to with
, but really only passes one of them. You're not going to be able to accomplish what you want without some sort of multicast delegate implementation (one that involves looping); JavaScript/ECMAScript don't have any built-in means of modifying multiple properties / calling multiple methods with a single assignment / call.
function multicast()
{
this.targets = Array.prototype.slice.call(arguments, 0);
}
multicast.prototype = {
call: function(methodName)
{
var i;
for (i=0; i<this.targets.length; ++i)
{
if ( this.targets[i][methodName] )
this.targets[i][methodName].apply(this.targets[i],
Array.prototype.slice.call(arguments, 1));
}
},
set: function(propName, value)
{
var i;
for (i=0; i<this.targets.length; ++i)
this.targets[i][propName] = value;
}
};
var object1 = { attribute: 3 };
var object2 = { attribute: 2, method: function() { alert('blah'); } };
var object3 = { method: function() {alert('bleh'); } };
var value = 4;
var delegate = new multicast(object1, object2, object3);
delegate.set('attribute', value);
delegate.call('method');
alert(object1.attribute + object2.attribute);