我可以使用ECMAScript的`with`语句通过单个操作来定位多个对象吗?

cre*_*gox 0 javascript actionscript-3 with-statement ecma262

以下不起作用(虽然它没有明确的错误),但为什么不呢?

并且...是否真的没有办法解决它,严格使用with语句?忘记使用for/foreach.

with (object1, object2) {
  attribute = value;
  method();
}
Run Code Online (Sandbox Code Playgroud)

编辑:抱歉在1中提出2个问题.我会尽量让它更清晰:

  1. 为什么上面的代码没有给出语法错误,不起作用但被接受with

  2. 如果可能的话,我们如何使用相同的属性更改多个对象with

希望以下示例将更清楚我想要实现的目标:

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
Run Code Online (Sandbox Code Playgroud)

Sho*_*og9 6

引入多对象范围 with

这是我原先以为你所追求的,因为你没有指明你的预期结果.只需堆叠with语句:

var object1 = { attribute: 3 };
var object2 = { method: function() { alert('blah'); } };

var value = 4;

with (object1) 
with (object2) 
{
  attribute = value;
  method();
}

alert(object1.attribute);
Run Code Online (Sandbox Code Playgroud)

当然,最内层引入的对象with将覆盖任何外部作用域中相同命名的属性,包括外部with语句的属性.

标准免责声明适用于性能命中和因使用而导致的错误with.请注意,您的示例显示了.在块内作为前缀的属性访问,但这是不正确的 - with修改范围,暂时将对象放在解析链的前面,因此不需要(或允许)前缀.


定位多个对象

关于你的编辑:逗号运算符允许你编写似乎传递多个表达式的东西with,但实际上只传递其中一个.如果没有某种多播委托实现(涉及循环的实现),你将无法完成你想要的东西; JavaScript/ECMAScript没有任何修改多个属性的内置方法/使用单个赋值/调用调用多个方法.

快速'n'脏实施:

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;
  }
};
Run Code Online (Sandbox Code Playgroud)

用法:

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);
Run Code Online (Sandbox Code Playgroud)