我已经创建了一个对象,并将其分配给3个变量,就像这样。
var barChartOptions, longChartOptions, scatterOptions;
barChartOptions = longChartOptions = scatterOptions = {
legend: {
display: false
},
scales: {
...
}
};
也试过
var barChartOption = longChartOptions = scatterOptions = {
legend: {
display: false
},
scales: {
...
}
};
然后我试着给其中一个变量添加一个键。这个键只针对这一个变量,其余的变量都是一样的。
longChartOptions.aspectRatio = 3;
现在,所有三个变量都有一个键 aspectRatio
. 为什么会出现这种情况?我知道如果我分别定义这三个变量,问题就不会发生,但这个对象很长,我想保持代码的干燥。
你可以使用传播操作符将一个对象复制到另一个变量中。
var barChartOption = {...longChartOptions} = {...scatterOptions} = {
legend: {
display: false
},
scales: {
// ...
}
};
实际上,当你使用=符号将一个对象复制到一个变量中时,javascript会将对象的引用复制到该变量中。因此,当你在任何一个变量上改变任何东西时,它也会反映到另一个变量上。
为了摆脱这种情况,你可以使用传播操作符或@CertainPerformance提到的过程。
做一个返回对象的函数,并在定义每个变量时调用该函数。
const makeOptions = () => ({
legend: {
display: false
},
scales: {
// ...
}
});
const barChartOptions = makeOptions(),
longChartOptions = makeOptions(),
scatterOptions = makeOptions();
为什么会出现这种情况?
因为赋值解析到赋值。你原来的代码。
barChartOptions = longChartOptions = scatterOptions = { /* ... */ };
相当于:
scatterOptions = { /* ... */ };
longChartOptions = scatterOptions; // references same object
barChartOptions = longChartOptions; // references same object
// so in the end, scatterOptions === barChartOptions
每个变量名都会引用内存中的同一个对象。当你把同一个对象赋值给不同的变量名时,不会发生结构的克隆。
问题是所有的变量都指向同一个内存块。你可以使用es6传播操作符,它将创建不同的实例。
var barChartOptions, longChartOptions, scatterOptions;
{...barChartOptions} = {...longChartOptions} = {...scatterOptions} = {
legend: {
display: false
},
scales: {
...
}
};