0

以下不起作用(尽管它没有给出明确的错误),但为什么不呢?

而且......真的没有办法绕过它,严格使用with 语句吗?忘记使用 for / foreach

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

编辑:很抱歉在 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
4

2 回答 2

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);

自然,最内层引入的对象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;
  }
};

用法:

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);
于 2011-05-02T21:49:32.160 回答
2

如果你想让你的代码更短,你也可以使用对对象的引用:

var o1 = object1
,   o2 = object2
;
o1.attribute = value;
o2.method();
于 2011-05-02T21:50:23.410 回答