Почему эти задания по деструктурированию не эквивалентны?
Я пытаюсь вложить эти деструктивные задания так, чтобы context1
а также context2
инициализируются в market[pair.context]
а также market[pair.target]
соответственно:
// 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;
Я думал, что этот правильный путь будет выглядеть так:
const {
[pair.context]: context1 = {},
[pair.target]: context2 = {},
} = {
[pair.market]: market = {},
} = this;
Однако когда market[pair.context]
или же market[pair.target]
уже существует, он не ведет себя так, как ожидалось.
Я довольно новичок в разрушении, но я полон решимости справиться с этим. Почему это так, и как я могу объединить первые две деструктуры?
Соответствующий код для тестирования:
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);
2 ответа
Деструктурирующее назначение всегда оценивается с правой стороны от назначения (что верно для всех назначений). Например:
const { foo, bar } = foobar;
Всегда буду оценивать foobar
и не foo
ни bar
потому что нет способа оценить до двух значений. Тем не менее, когда вы соединяете вместе такие вещи:
const { foo } = { bar } = foobar;
Вы:
- Создание неявного глобального
bar
(при условии, что вы не объявляете это первым) - не хорошо - Назначение
foo
как деструктурировано изfoobar
Во-первых, переводчик видит const { foo } = …
, Затем он оценивает правую часть этого задания по деструктуризации, чтобы увидеть, что он будет разрушать, { bar } = foobar
, по существу { bar } = foobar
сначала будет выполнено эффективно (потому что оно оценивается, чтобы получить правую часть внешнего назначения), затем будет оцениваться foobar
как упомянуто выше. затем const { foo } = foobar
выполняется. Так:
const { x } = { y } = {
x: 1,
y: {
x: 6
}
}
Дам тебе x
как 1 и y
как { x: 6 }
- нет x
как 6, как предполагалось. Это так же, как:
const obj = {
x: 1,
y: {
x: 6
}
}
const { x } = obj;
({ y } = obj); //No declarator, parentheses for "expression coercion"
Но есть также синтаксис ES2015, который позволяет вам глубоко вкладывать деструктурирующее назначение:
const {
[pair.market]: market = {},
[pair.market]: {
[pair.context]: context1 = {},
[pair.target]: context2 = {}
}
} = this;
Я бы никогда не выбрал краткость, а не читабельность, так что у вас просто две разборки.
Используя игровую площадку Babel, мы видим, насколько функционально эквивалентен код. Я упростил ваш пример:
const {
[pair.context]: context1 = {},
} = {
[pair.market]: market = {},
} = markets;
компилируется в
var _markets, _markets$pair$market;
var _pair$market = (_markets = markets, _markets$pair$market = _markets[pair.market], market = _markets$pair$market === undefined ? {} : _markets$pair$market, _markets),
_pair$market$pair$con = _pair$market[pair.context],
context1 = _pair$market$pair$con === undefined ? {} : _pair$market$pair$con;
Это немного запутанно, но вы можете видеть следующие задания:
_markets = markets;
_pair$market = _markets;
_pair$market$pair$con = _pair$market[pair.context]
context1 = _pair$market$pair$con
Так твой код
const {
[pair.context]: context1 = {},
[pair.target]: context2 = {},
} = {
[pair.market]: market = {},
} = this;
по сути следующие задания:
const market = this[pair.market];
const context1 = this[pair.context];
const context2 = this[pair.target];
Что не то, что вы хотите.
Боюсь, вам придется разбить его на две строки. Это также легче читать. Нет смысла в том, чтобы ставить одну строчку и заставлять людей ломать голову, пытаясь понять это утверждение.