samcorcos samcorcos - 4 months ago 14
Javascript Question

Assign key to multiple objects

Is it possible to assign a value to multiple JavaScript objects at the same time?

Obviously this can be done with a for loop etc, but I'm curious if there's something in the new version of the language that makes this possible. Similar syntax already exists in a number of other languages, I just can't find the JavaScript equivalent.

Ideally, the syntax would look something like this:

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


You are effectively looking for lenses, which can abstract over such operations and also provide multiple targets. There are various JS implementations around, though I didn't find any that uses lists. With them, it would look something like

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

But that's ugly, right? And you were asking for new ES6 features. Yes, a Proxy can help us make this a lot more beautiful indeed:

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

Here's how you'd implement such a function:

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 = => x[property]);
      if (values.every(v => typeof v == "function")) {
        function fnList(...args) {
          return => v[property](...args));
        fnList.values = values;
        values = fnList;
      return new Proxy(values, handler);  
  return function ListProxy(...args) { return new Proxy(els, handler); };

The get method is not so vitally important, but it does allow for deeper chaining and even function calls instead of assignments:

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