ES6模块不变性

时间:2018-01-29 21:46:21

标签: ecmascript-6 vue.js es6-modules

我认为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 个答案:

答案 0 :(得分:2)

导入的绑定不可分配,即全部。它们类似于const - 您无法更改变量but you can mutate the object it holds。为防止这种情况,请在导出时冻结对象:

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

我怎样才能使每个组件都有colors数组的新实例?

请注意Copying array by value in JavaScriptcolors.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];

答案 1 :(得分:1)

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

您可以创建数组的浅表副本并对其进行操作:

const copiedColors = [...colors];

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