我可以使用 ECMAScript 的“with”语句通过一次操作来定位多个对象吗?

发布于 2024-11-05 03:50:03 字数 1043 浏览 5 评论 0原文

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

而且......是否真的没有办法解决这个问题,严格使用with 声明?忘记使用 for / foreach

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

编辑:很抱歉在 1 中提出了 2 个问题。我会尽力使其更清楚:

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

  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

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:

  1. Why the code above gives no syntax error, doesn't work but is accepted by with?

  2. 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟柳画桥 2024-11-12 03:50:03

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

Introducing multi-object scope with 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).


Targeting multiple objects

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.

Quick 'n' dirty implementation:

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

Usage:

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);
℡Ms空城旧梦 2024-11-12 03:50:03

如果您想让代码更短,您还可以使用对该对象的引用:

var o1 = object1
,   o2 = object2
;
o1.attribute = value;
o2.method();

You can also use a reference to the object if you want to make your code shorter:

var o1 = object1
,   o2 = object2
;
o1.attribute = value;
o2.method();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文