Я знаю, что ES6 еще не стандартизирован, но многие браузеры в настоящее время поддерживают const
ключевое слово в JS.
В спецификации написано, что:
Значение константы не может измениться посредством повторного присвоения, и константа не может быть повторно объявлена. Из-за этого, хотя можно объявить константу без ее инициализации, это было бы бесполезно.
и когда я делаю что-то вроде этого:
const xxx = 6;
xxx = 999;
xxx++;
const yyy = [];
yyy = 'string';
yyy = [15, 'a'];
Вижу, что все ок, xxx
по-прежнему 6
и yyy
есть []
.
Но если я это сделаю yyy.push(6); yyy.push(1);
, мой постоянный массив изменится. Прямо сейчас он есть, [6, 1]
и я, кстати, до сих пор не могу его изменить yyy = 1;
.
Это ошибка или я что-то упускаю? Пробовал в последнем хроме и FF29
javascript
ecmascript-6
const
Сальвадор Дали
источник
источник
Ответы:
В документации указано:
Когда вы добавляете в массив или объект, вы не переназначаете или повторно объявляете константу, она уже объявлена и назначена, вы просто добавляете ее в «список», на который указывает константа.
Итак, это отлично работает:
и это:
но ни то, ни другое:
источник
Это происходит потому, что ваша константа фактически хранит ссылку на массив. Когда вы присоединяете что-то к своему массиву, вы изменяете не постоянное значение, а массив, на который оно указывает. То же самое произойдет, если вы назначите объект константе и попытаетесь изменить любое ее свойство.
Если вы хотите заморозить массив или объект, чтобы его нельзя было изменить, вы можете использовать
Object.freeze
метод, который уже является частью ECMAScript 5.источник
five
установленная на 5, на самом деле не имеет значения 5, это просто ссылка на число 5. Поэтому, если я этоfive++
сделаю, я не изменяю константу, а только число, на которое она указывает.five
указывает переменная (переменнаяfive
раньше была меткой для числа 5, теперь она указывает на другое число: 6). В примере в вопросе (и в этом ответе)x
всегда указывает на один и тот же список; еслиx
это const, вы не можете указать на другой список. Единственная разница в том, что один и тот же список может увеличиваться или уменьшаться; это возможно только для массивов и объектов, но не для примитивов.Это последовательное поведение со всеми языками программирования, которые я могу придумать.
Рассмотрим C - массивы - это просто прославленные указатели. Постоянный массив означает только то, что значение указателя не изменится, но на самом деле данные, содержащиеся по этому адресу, свободны.
В javascript вам разрешено вызывать методы константных объектов (конечно - иначе константные объекты не имели бы особого смысла!). Эти методы могут иметь побочный эффект изменения объекта. Поскольку массивы в javascript являются объектами, это поведение применимо и к ним.
Все, в чем вы уверены, - это то, что константа всегда будет указывать на один и тот же объект. Свойства самого объекта можно изменять.
источник
Кроме того, еще одно важное замечание:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
источник
Я думаю, это дало бы вам больше ясности в вопросе: https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0 .
По сути, это сводится к тому, что
const
всегда указывается один и тот же адрес в памяти. Вы можете изменить значение, хранящееся в этом адресе, но не можете изменить адрес, наconst
который он указывает.Упомянутое
const
вами определение будет истинным, когдаconst
указывает на адрес, содержащий примитивное значение. Это связано с тем, что вы не можете присвоить ему значение,const
не изменив его адрес (потому что так работает присвоение примитивных значений), а изменение адреса aconst
запрещено.Если, как если бы
const
это указывает на непримитивное значение, можно изменить значение адреса.источник
Я прочитал эту статью, пока искал, почему мне удалось обновить объект даже после определения его как
const
. Итак, дело здесь в том, что обновлять можно не непосредственно объект, а содержащиеся в нем атрибуты.Например, мой объект выглядит так:
В приведенных выше ответах правильно указано, что это объект, который является константой, а не его атрибутом. Следовательно, я смогу обновить идентификатор или имя, выполнив:
Но я не смогу обновить сам объект, например:
источник
Поскольку в const вы можете изменять значения объекта, поэтому объект фактически не хранит данные о назначении, а вместо этого указывает на них. так что есть разница между примитивами и объектами в Javascript.
источник