扩展语法对于对象数组不能按预期工作

zyl*_*ylo 1 javascript ecmascript-6 reactjs babeljs spread-syntax

我有一个反应组件,我试图将对象传播到构造函数中的状态。

constructor() {
    super()

    const shapesArray = [1, 2, 3]

    let renderStates = shapesArray.map((el, i) => {
        return {['shape'+i]: 'black'}
    })

    this.state = { ...renderStates }
    console.log(this.state)
}
Run Code Online (Sandbox Code Playgroud)

我想通过执行以下操作来访问颜色this.state.shape0,但是当我控制台 log 时this.state,我得到:

在此输入图像描述

代替Object {shape0: "black", shape1: "black", shape2: "black"}

我在这里做错了什么?

Alu*_*dad 6

那是因为您正在将数组扩展到对象中。数组实际上是用(通常)连续的整数字符串作为键的对象。这些键是数组的索引。

如下所示,map获取一个数组并生成另一个数组

const shapesArray = [1, 2, 3];

const renderStates = shapesArray.map((el, i) => {
  return {
    ['shape' + i]: 'black'
  };
});

console.log(renderStates);
Run Code Online (Sandbox Code Playgroud)

当传播到对象中时,源对象中每个自己的可枚举属性的值都会在其各自的键下添加到目标中。由于数组的键是它的索引,因此您最终会得到一个对象,该对象具有数组每个元素的属性。每个属性的名称是其在数组中的索引。

为了实现您想要的目的,您可以使用Array.prototype.reduce在映射过程中创建的名称从数组构建一个对象。

const shapesArray = [1, 2, 3];

const renderStates = shapesArray
  .map((el, i) => {
    return {
      ['shape' + i]: 'black'
    };
  })
  .reduce((o, element) => {
    Object.keys(element).forEach(key => o[key] = element[key]);
    return o;
  }, {});

console.log(renderStates);
Run Code Online (Sandbox Code Playgroud)

当然,通过将对象分散到reduce内部,这本身可以写得更优雅。

const shapesArray = [1, 2, 3];

const renderStates = shapesArray
  .map((el, i) => {
    return {
      ['shape' + i]: 'black'
    };
  })
  .reduce((o, element) => ({...o, ...element}), {});

console.log(renderStates);
Run Code Online (Sandbox Code Playgroud)