JS - 在一个变量中添加键,将其添加到所有在链式赋值中创建的变量中。

问题描述 投票:0回答:1

我已经创建了一个对象,并将其分配给3个变量,就像这样。

var barChartOptions, longChartOptions, scatterOptions;
barChartOptions = longChartOptions = scatterOptions = {
    legend: {
        display: false
    },
    scales: {
        ...
    }
};

也试过

var barChartOption = longChartOptions = scatterOptions = {
    legend: {
        display: false
    },
    scales: {
        ...
    }
};

然后我试着给其中一个变量添加一个键。这个键只针对这一个变量,其余的变量都是一样的。

longChartOptions.aspectRatio = 3;

现在,所有三个变量都有一个键 aspectRatio. 为什么会出现这种情况?我知道如果我分别定义这三个变量,问题就不会发生,但这个对象很长,我想保持代码的干燥。

javascript chaining
1个回答
2
投票

你可以使用传播操作符将一个对象复制到另一个变量中。

var barChartOption = {...longChartOptions} = {...scatterOptions} = {
    legend: {
        display: false
    },
    scales: {
      // ...
    }
};

实际上,当你使用=符号将一个对象复制到一个变量中时,javascript会将对象的引用复制到该变量中。因此,当你在任何一个变量上改变任何东西时,它也会反映到另一个变量上。

为了摆脱这种情况,你可以使用传播操作符或@CertainPerformance提到的过程。


4
投票

做一个返回对象的函数,并在定义每个变量时调用该函数。

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

每个变量名都会引用内存中的同一个对象。当你把同一个对象赋值给不同的变量名时,不会发生结构的克隆。


1
投票

问题是所有的变量都指向同一个内存块。你可以使用es6传播操作符,它将创建不同的实例。

var barChartOptions, longChartOptions, scatterOptions;
{...barChartOptions} = {...longChartOptions} = {...scatterOptions} = {
    legend: {
        display: false
    },
    scales: {
        ...
    }
};
© www.soinside.com 2019 - 2024. All rights reserved.