为什么这些解构任务不等同?

时间:2018-01-07 05:53:20

标签: javascript ecmascript-6 destructuring object-destructuring

我正在尝试嵌套这些解构分配,以便context1context2分别初始化为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 :(得分:3)

解构赋值总是评估到赋值的右侧(对于所有赋值都是如此)。例如:

const { foo, bar } = foobar;

始终评估为foobar而非foobar,因为无法评估为两个值。也就是说,当你把这样的事情联系在一起时:

const { foo } = { bar } = foobar;

你是:

  1. 创建一个隐含的全局bar(假设你没有先声明它) - 不好
  2. foo
  3. 分配foobar为结构

    首先,口译员看到const { foo } = …。然后evaluates the right-hand-side of that destructuring assignment查看它将构造的内容{ 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; 
    

    我永远不会选择简洁而不是可读性,所以你可以通过两次单独的解构来完成。

答案 1 :(得分:2)

使用Babel playground,我们可以看到代码在功能上是如何等效的。我简化了你的例子:

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

这不是你想要的。

我担心你必须把它分成两行。它也更容易阅读。没有什么真正的价值可以放在一条线上,让人们不敢试图理解这句话。