代码之家  ›  专栏  ›  技术社区  ›  Matt Gween

ES6模块不变性

  •  1
  • Matt Gween  · 技术社区  · 6 年前

    我认为ES6模块导出总是不可变的,所以我对自己的行为感到非常困惑。我有一个简单的颜色数组,我想在Vue应用程序的多个组件中使用它。它位于自己的文件中,如下所示:

    export const colors = [
      '#ffb3ba',
      '#ffdfba',
      '#ffffba',
      '#bae1ff',
    ]
    

    然后我将其导入到我想要使用的组件中,如下所示:

    import { colors } from '../assets/colors';
    

    我有一个函数,用于拾取随机颜色,然后将其从列表中删除,这样就不会为同一组件再次拾取该颜色。是这样的。

    descriptions.forEach(item => {
          const colorIndex = Math.floor(Math.random() * colors.length);
          item['color'] = colors[colorIndex];
          colors.splice(colorIndex, 1);
        });
    

    这里的想法是从列表中选择一种随机颜色,为其指定一个描述,然后将其从列表中删除,以便在 forEach .

    问题是,它似乎正在从列表中永久删除颜色。因此,当我导入并尝试在另一个组件中使用数组时,其中没有颜色。我怎样才能使它成为 colors 每个组件的阵列?

    2 回复  |  直到 6 年前
        1
  •  7
  •   Bergi    6 年前

    导入的 绑定 是不可分配的,仅此而已。它们类似于 const -不能更改变量, but you can mutate the object it holds . 要防止出现这种情况,请在导出对象时冻结该对象:

    export const colors = Object.freeze([
      '#ffb3ba',
      '#ffdfba',
      '#ffffba',
      '#bae1ff',
    ]);
    

    我怎样才能使它成为 colors 每个组件的阵列?

    看看 Copying array by value in JavaScript 为此:只是 colors.slice() . 您还需要退房 How to randomize (shuffle) a JavaScript array? 对于如何有效地获得描述的随机颜色,甚至 some answers 不会改变输入。

    import { colors } from '../assets/colors';
    import { shuffle } from '…';
    const randomColors = shuffle(colors.slice());
    console.assert(descriptions.length <= randomColors.length);
    for (const [i, description] of descriptions.entries())
      description.color = randomColors[i];
    
        2
  •  3
  •   TimoStaudinger    6 年前

    正如您正确观察到的那样,ES6模块导入不是不变的。


    您可以创建阵列的浅层副本并对其进行操作:

    const copiedColors = [...colors];
    
    descriptions.forEach(item => {
      const colorIndex = Math.floor(Math.random() * colors.length);
      item['color'] = copiedColors[colorIndex];
      copiedColors.splice(colorIndex, 1);
    });