JS - Добавление ключа к одной переменной добавляет его ко всем переменным, созданным в цепочечном присваивании - PullRequest
0 голосов
/ 28 апреля 2020

Я создал объект и присвоил его трем переменным, например:

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

также попытался

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

Затем я попытался добавить ключ к одной из переменных. Этот ключ указывает только c на эту одну переменную, а остальная часть объекта одинакова для всех переменных.

longChartOptions.aspectRatio = 3;

Теперь все три переменные имеют ключ aspectRatio. Почему это происходит? Я понимаю, что если я определю три переменные по отдельности, проблема не возникнет, но объект довольно длинный, и я хочу сохранить код DRY.

Ответы [ 3 ]

4 голосов
/ 28 апреля 2020

Создайте функцию, которая возвращает объект, и вызовите эту функцию при определении каждой переменной:

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

Каждое имя переменной ссылается на один и тот же объект в памяти. Клонирование структуры не происходит, когда вы назначаете один и тот же объект другому имени переменной.

2 голосов
/ 28 апреля 2020

Вы можете использовать оператор распространения, чтобы скопировать объект в другую переменную.

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

На самом деле, когда вы используете знак = для копирования объекта в переменную javascript копирует ссылку на объект в эта переменная. Поэтому, когда вы изменяете что-либо в любой переменной, она также отражает другую.

Чтобы избавиться от этого, вы можете использовать оператор распространения или процесс, упомянутый @ CertainPerformance.

1 голос
/ 28 апреля 2020

Проблема в том, что все переменные указывают на один и тот же блок памяти. Вы можете использовать оператор распространения es6, который будет создавать разные экземпляры.

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