Array slice()提供引用而不是值

时间:2018-04-06 20:08:45

标签: javascript angular typescript

我有一个文件,我可以导出这样的对象:

export const LINECHART2_DATA = {
    series: [{
        data: [],
        name: 'HR',
    },
    { 
        etc...
    }]
}

我这样导入它:

import { LINECHART2_DATA } from '../chart-options/options';

我有以下方法:

prepareLineChartDataContainer(bed: BedDetails) {
//Clear data to prepare for new bed
if (bed.seriesContainer == null) {
  bed.seriesContainer = LINECHART2_DATA.series.slice();
} else {
  bed.seriesContainer.forEach(series => {
    series.data.length = 0;
  });
}
//Add data to seriesContainer
this.vitalSigns.forEach(vs => {
  bed.timeWindows.forEach(tw => {
    bed.seriesContainer.find(series => series.name == vs).data.push(tw['avg' + vs]);
  });
});
}

正如您在上面所看到的,我从LINECHART2_DATA切片系列数组,然后将一些数据推送到它。当新的bed以空seriesContainer传递给方法时,它将再次被切片,但这次它将包含之前bed添加的数据。由于我使用的是slice(),因此我希望得到LINECHART2_DATA的值,而不是参考值。我做错了什么?

2 个答案:

答案 0 :(得分:5)

来自documentation of Array.slice

  

切片不会改变原始数组。它返回浅拷贝   原始数组中的元素。原始数组的元素是   复制到返回的数组中,如下所示:

     

对于对象引用(而不是实际对象),slice复制对象   引用到新数组中。 原始阵列和新阵列都参考   对于同一个对象。如果引用的对象发生更改,则更改为   对新的和原始数组都可见。

     

对于字符串,数字和   布尔值(不是String,Number和Boolean对象),slice复制   值到新数组中。对字符串,数字或布尔值的更改   一个数组不影响另一个数组。如果添加了新元素   无论是数组,另一个数组都不受影响。

因此,您所看到的行为是切片的浅拷贝行为的结果。如果您需要深层复制以便可以自由地改变对象而不影响原件,则需要手动执行此操作。 The answers to this question显示了一些方法。

答案 1 :(得分:0)

为防止复制数组的元素发生变异,您还应创建项目副本:

 bed.seriesContainer = LINECHART2_DATA.series.map((item=>Object.assign({}, item, {data: item.data.slice()}))