Почему эти задания по деструктурированию не эквивалентны?

1

Я пытаюсь context1 эти назначения деструктурирования, так что 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
    Не могли бы вы сделать тестовый набор меньше и удалить контекст / домен вашего кода, чтобы его было легче понять? У меня сейчас проблемы с пониманием того, чего ты пытаешься достичь здесь.
  • 0
    Я пытаюсь вложить назначения деструктурирования так, чтобы context1 и context2 были инициализированы для market[pair.context] и market[pair.target] соответственно
Показать ещё 1 комментарий
Теги:
ecmascript-6
destructuring

2 ответа

3
Лучший ответ

Назначение дефрагментации всегда оценивает правую часть задания (что верно для всех присвоений). Например:

const { foo, bar } = foobar;

Всегда будет оценивать foobar а не foo и bar потому что нет возможности оценить два значения. Тем не менее, когда вы объединяете такие вещи:

const { foo } = { bar } = foobar;

Вы:

  1. Создание неявного глобального bar (предполагая, что вы его не объявляете первым) - не хорошо
  2. Присвоение 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; 

Я бы никогда не выбрал краткость в отношении читаемости, поэтому вы просто отлично справляетесь с двумя отдельными деконструкциями.

  • 0
    Спасибо за обновление, последний блок кода - это то, что я пытался выяснить, не осознавал, что могу дважды [pair.market] деструктуризацию из [pair.market] . this.market проверить и посмотреть, что произойдет, если this.market не определен
  • 0
    @neaumusic Да, я тоже понятия не имел, но решил попробовать и работает. Классное следствие разрушения вложенного объекта.
2

Используя детскую площадку 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;

Он abit запутанный, но вы можете видеть следующие задания:

_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];

Это не то, что вы хотите.

Боюсь, вам придется разбить его на две линии. Это также легче читать. Никакая реальная ценность в том, чтобы положить в одну линию и заставить людей почесать голову, пытаясь понять утверждение.

  • 1
    Будучи придирчивым, но я бы не сказал, «это то, как код на самом деле трансформируется», потому что браузеры поддерживают ES2015, никакого преобразования не требуется, и я бы не подумал, что OP использует Babel. Я бы сказал «функционально эквивалентный».
  • 0
    @ Li357 Вы сделали очень хорошую мысль! Спасибо за исправление. Изменили его в своей формулировке (:

Ещё вопросы

Сообщество Overcoder
Наверх
Меню