我有一个文件,我可以导出这样的对象:
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
的值,而不是参考值。我做错了什么?
答案 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()}))