I'm trying to nest these destructuring assignments such that context1
and context2
are initialized to market[pair.context]
and market[pair.target]
respectively:
// set market to this[pair.market] or empty object
const {
[pair.market]: market = {},
} = this;
// set context1 to market[pair.context] or empty object
// set context2 to market[pair.target] or empty object
const {
[pair.context]: context1 = {},
[pair.target]: context2 = {},
} = market;
I thought this correct way would be like this:
const {
[pair.context]: context1 = {},
[pair.target]: context2 = {},
} = {
[pair.market]: market = {},
} = this;
However, when market[pair.context]
or market[pair.target]
already exist, it doesn't seem to behave as expected.
I'm fairly new to destructuring, but I'm determined to master it. Why is this the case, and how can I combine the first two destructures?
Relevant code for testing:
const pair1 = {
context: 'A',
target: 'B',
market: 'MARKET1',
price: '0.1',
};
const pair2 = {
context: 'A',
target: 'C',
market: 'MARKET1',
price: '1',
};
const pair3 = {
context: 'C',
target: 'B',
market: 'MARKET2',
price: '0.1',
};
// markets
function addPair (pair) {
const {
[pair.market]: market = {},
} = this;
const {
[pair.context]: context1 = {},
[pair.target]: context2 = {},
} = market;
this[pair.market] = {
...market,
[pair.context]: {
...context1,
[pair.target]: {
price: +(pair.price),
},
},
[pair.target]: {
...context2,
[pair.context]: {
price: +(1 / pair.price),
},
},
};
}
const markets = {};
addPair.call(markets, pair1);
addPair.call(markets, pair2);
addPair.call(markets, pair3);
console.log(markets);
Destructuring assignment always evaluates to the right-hand-side of the assignment (which is true for all assignment). For example:
const { foo, bar } = foobar;
Will always evaluate to foobar
and not foo
nor bar
because there is no way to evaluate to two values. That said, when you chain together things like this:
const { foo } = { bar } = foobar;
You are:
bar
(assuming you're not declaring it first) — not goodfoo
as destructured from foobar
First, the interpreter sees const { foo } = …
. Then it evaluates the right-hand-side of that destructuring assignment to see what it will destructure, { bar } = foobar
. Essentially { bar } = foobar
will be performed first effectively (because it's evaluated in order to get the right-hand-side of the outer assignment), then will evaluate to foobar
as mentioned above. Then const { foo } = foobar
is performed. So:
const { x } = { y } = {
x: 1,
y: {
x: 6
}
}
Will give you x
as 1 and y
as { x: 6 }
— not x
as 6 as assumed. It's the same as:
const obj = {
x: 1,
y: {
x: 6
}
}
const { x } = obj;
({ y } = obj); //No declarator, parentheses for "expression coercion"
But there's also ES2015 syntax that allows you to deeply nest destructuring assignment:
const {
[pair.market]: market = {},
[pair.market]: {
[pair.context]: context1 = {},
[pair.target]: context2 = {}
}
} = this;
I would never choose brevity over readability so you're just fine with two separate deconstructions.