It would be nice to have something like "destructed with" - with(point.{x, y}){...}

# Igor Baklan (8 years ago)

It would be nice to have something like "destructed with" - with(point.{x,y}){...}

Well known issue with with is that it may provide some "noise" (some unwonted names) into scope, plus code inside with can be poorly optimize, since names can not be resolved statically inside it body.

While using something similar to object destructuring can make things better for with construct

In general it might look like:

const point0 = {x:10, y:11};
const point1 = {x:20, y:22};
const point2 = {x:0,  y:0};

with(point0.{x0: x, y0: y}) with(point1.{x1: x, y1: y}) with(point.{x, y}) {
  x = x0 + x1;
  y = y0 + y1;
}

log(point2); // Object {x: 30, y: 33}

Essentially that it should only limit the set of names that are exposed from target object (it should not create shadowing variables which initialized with values of that filed), and optionally rename some stuff from target object, also without creating new variables initialized with values from that filed, but only provide access to that (same) properties just (maybe) by the means of arbitrary names. So if some "side effect" was made over that renamed properties it should be visible through initial target object that was passed into with construct.

From some perspective this construct might looks very similar to

const point0 = {x:10, y:11};
const point1 = {x:20, y:22};
const point2 = {x:0,  y:0};

with({x0:x,y0:y} = point0) with({x1:x,y1:y} = point1) with(point2) {
  x = x0 + x1;
  y = y0 + y1;
}

log(point2); // Object {x: 30, y: 33}

But difference in that, if destructed fields will be changed inside with-block body, (in case above) it will not cause modification of initial object fields, while construct like:

const point2 = {x:0,  y:0};
with(point2.{x2:x, y2:y}) {
  x2 = 100;
  y2 = 101;
}

log(point2); // Object {x: 100, y: 101}

should modify initial (point2) object state.

Also it would be nice to have constructs like

with(point: Point) {
  /*.. some code where only .x and .y properties of point object are visible*/
}

However in this case not very clear what should be allowed as "property names provider" and it also complicates static analyse of with-block body since PropertyNamesProvider object can be available only at runtime (but still this looks pretty natural).

An other option can be use as keyword instead of ., then it might look like

const point2 = {x:0,  y:0};
with(point2 as {x2:x, y2:y}) {
  x2 = 100;
  y2 = 101;
}

log(point2); // Object {x: 100, y: 101}