将键分配给多个对象

时间:2016-08-27 19:05:51

标签: javascript ecmascript-6

是否可以同时为多个JavaScript对象分配值?

显然这可以通过for循环等来完成,但我很好奇是否有新版本的语言可以实现这一点。类似的语法已经存在于许多其他语言中,我只是找不到相应的JavaScript。

理想情况下,语法看起来像这样:

{App1, App2, App3}.foo = "bar"

App1.foo === "bar" // true
App2.foo === "bar" // true

5 个答案:

答案 0 :(得分:2)

没有本地方法可以做到这一点。但是,如果您只是在寻找类似的语法,那么您可以执行类似的操作。您可以创建一个代理功能,为您完成。

var _ = (...args) => {
    var proxy = new Proxy(args, {
        set: (target, property, value) => {
            target.forEach(object => object[property] = value);
        }
    });
    return proxy;
};

var App1 = {}, App2 = {}, App3 = {};

_(App1, App2, App3).value = {
    foo: 'bar'
};

_(App1, App2, App3).someOtherValue = {
    foo: 'baz'
};

console.log(App1); // { value: { foo: 'bar' }, someOtherValue: { foo: 'baz' } }
console.log(App2); // { value: { foo: 'bar' }, someOtherValue: { foo: 'baz' } }
console.log(App3); // { value: { foo: 'bar' }, someOtherValue: { foo: 'baz' } }

答案 1 :(得分:2)

你正在寻找镜头,它可以抽象出这些操作并提供多个目标。有各种JS实现,虽然我没有找到任何使用列表。有了它们,它看起来像

set(onList(property("foo")), [App1, App2, App3]);

但那很难看,对吧?你要求新的ES6功能。是的,一个Proxy可以帮助我们确保它变得更加美丽:

ListProxy(App1, App2, App3).foo = "bar";

以下是您如何实施此功能:

const ListProxy = (() => {
  const handler = {
    set(target, property, value) {
      for (const t of target)
        t[property] = value;
    },
    get(target, property) {
      if (typeof target == "function")
        target = target.values;
      const maybe = target.filter(x => property in Object(x));
      if (maybe.length == 0) return undefined;
      let values = maybe.map(x => x[property]);
      if (values.every(v => typeof v == "function")) {
        function fnList(...args) {
          return maybe.map(v => v[property](...args));
        }
        fnList.values = values;
        values = fnList;
      }
      return new Proxy(values, handler);  
    }
  };
  return function ListProxy(...args) { return new Proxy(args, handler); };
})();

get方法并不是那么重要,但它确实允许更深层次的链接甚至函数调用而不是赋值:

ListProxy({value:"ax"}, {value:"by"}).value[0].toUpperCase(); // ["A","B"]

答案 2 :(得分:0)

制作类似你提议的语法的唯一方法是扩展const App1 = {}, App2 = {}, App3 = {}; Object.defineProperty(Object.prototype, 'values', { set(value) { for (let prop in this) this[prop].value = value; } }); ({App1, App2, App3}).values = "foo"; console.log(App1.value);原型,无论是否认为这是一个好主意(它不是)。



{App1, App2, App2}.value




您永远无法编写{,因为JS解析器会将前导value解释为块的开头。因此需要将其括在括号中。

您无法使用value设置所有值,因为这会与您要在各个对象上设置的values属性冲突。因此,我们改为使用{{1}}。

答案 3 :(得分:-1)

我不认为这需要特殊的语法,我宁愿使用基本的ES6分配它:

const baz = { foo: "bar" };

<强> [App1, App2, App3].forEach(app => app.value = baz);

答案 4 :(得分:-1)

你可以使用:
App1.value = App2.value = {foo: "bar"};
或者
App1.value.foo = App2.value.foo = "bar";