Javascript ES6减少影响范围外阵列的功能

Javascript ES6减少影响范围外阵列的功能,javascript,node.js,ecmascript-6,Javascript,Node.js,Ecmascript 6,我将其改写为一个简化的形式来演示,我有一个选择器数组,其中有一个时间条目数组,我使用reduce在选择器上按类型汇总时间条目,然后使用第二个reduce在两个选择器上显示全局条目 每个选择器的第一次减少工作如预期。 第二个reduce on global time条目按预期工作,但以某种方式更改了第一个选择器(Sam)的条目 萨姆和约翰选择了同样的数额 苹果2小时,桃子2小时,柠檬1小时 有没有更好的方法写这个?有没有一个概念我没有理解 function testBug() { // Red

我将其改写为一个简化的形式来演示,我有一个选择器数组,其中有一个时间条目数组,我使用reduce在选择器上按类型汇总时间条目,然后使用第二个reduce在两个选择器上显示全局条目

每个选择器的第一次减少工作如预期。 第二个reduce on global time条目按预期工作,但以某种方式更改了第一个选择器(Sam)的条目

萨姆和约翰选择了同样的数额

苹果2小时,桃子2小时,柠檬1小时

有没有更好的方法写这个?有没有一个概念我没有理解

function testBug() {
  // Reducer Function
  function entryReducer(summary, entry) {
    // find an index if the types of fruit are the same
    let index = summary.findIndex((item) => {
      return item.type.id === entry.type.id;
    });

    if (index === -1) {
      summary.push(entry);
    } else {
      summary[index].hours = summary[index].hours + entry.hours;
    }
    return summary;
  }

  let pickers = [
    {
      id: 1,
      identifier: "Sam Smith",
      timeEntries: [
        {
          type: {
            id: 1,
            name: "Apples",
          },
          hours: 1,
        },
        {
          type: {
            id: 2,
            name: "Peaches",
          },
          hours: 1,
        },
        {
          type: {
            id: 3,
            name: "Lemons",
          },
          hours: 1,
        },
        {
          type: {
            id: 1,
            name: "Apples",
          },
          hours: 1,
        },
        {
          type: {
            id: 2,
            name: "Peaches",
          },
          hours: 1,
        },
      ],
    },
    {
      id: 2,
      identifier: "John Snow",
      timeEntries: [
        {
          type: {
            id: 1,
            name: "Apples",
          },
          hours: 1,
        },
        {
          type: {
            id: 2,
            name: "Peaches",
          },
          hours: 1,
        },
        {
          type: {
            id: 3,
            name: "Lemons",
          },
          hours: 1,
        },
        {
          type: {
            id: 1,
            name: "Apples",
          },
          hours: 1,
        },
        {
          type: {
            id: 2,
            name: "Peaches",
          },
          hours: 1,
        },
      ],
    },
  ];

  let pickersSummary = [];
  let timeEntriesSummary = [];

  for (const picker of pickers) {
    if (picker.timeEntries.length > 0) {
      // reduce time entries into an array of similar types
      picker.timeEntries = picker.timeEntries.reduce(entryReducer, []);
      // push to pickers summary arr
      pickersSummary.push(picker);
      // push time entries to a summary array for later reduce
      picker.timeEntries.map((entry) => timeEntriesSummary.push(entry));
    }
  }

  // Reduce time entries for all pickers
  // Sam & John pick the same amount
  // Apples 2h
  // Peaches 2h
  // Lemons 1h

  // **** If I run this Sam's entries are overwritten with the global time entries ***
  timeEntriesSummary = timeEntriesSummary.reduce(entryReducer, []);

  const results = { pickersSummary, timeEntriesSummary };

  console.log(results);
}
testBug();

module.exports = testBug;

即使通过每个reducer传递一个新数组
[]
,这些数组包含的实际对象也可以共享。这意味着,当您编辑数组“A”中的一个对象时,数组“B”中的对象也可能发生变化

您知道一些语言如何允许您通过值或引用传递变量,以及这如何从根本上改变值的处理方式吗?JavaScript技术上使用通过共享调用。我建议阅读另一个答案:

一旦数组中的一个元素被推入另一个数组中,它在内存中是独立的吗

不,不是。在JavaScript中,您将永远记得何时创建对象的单个副本(或者至少想要),因为这需要一些努力,请参见或

因此,就像使用
a=b
一样,
将(a)
推入数组引用原始对象。请参见此示例,其中有一个对象可通过两个变量(
x
y
)以及数组
z
的两个元素访问。因此,将其修改为
z[1]
会影响所有其他内容:

设x={a:5};
设y=x;
设z=[x];
z、 推(y);
z[1].a=4;
控制台日志(x);
控制台日志(y);
console.log(z[0]);

console.log(z[1])嗯。。我尝试过为第二个减速机编写一个单独的减速机函数,使用不同的变量名,但仍然没有成功。。当然,一旦数组中的一个元素被推送到另一个数组中,它在内存中是独立的吗?