Модули ES6 - почему имена const const не читаются
Я был читал о ES-модулях и экспериментировал и наткнулся на случай, который я не мог объяснить:
// settings.js
export const FOO = 42;
export const BAR= 5;
// main1.js
import * as settings from './settings';
settings.FOO = 1;
//main2.js
import {FOO, BAR} from './settings'
FOO = 1;
В main1.js
я могу переопределить значение const
через переменную settings
, но в main2.js
я не могу (как и ожидалось).
Вопрос (теоретический) заключается в том, почему в первом случае можно переопределить значение const
? Создает ли "просмотр только для чтения" просто создает свойства на обычном объекте и разбивает исходную структуру?
Практический вопрос будет самым эффективным способом возврата коллекции констант (или свойств только для чтения) из модуля? Я имел в виду следующее:
// settings.js
export default Object.freeze({
FOO: 42,
BAR: 5
});
Любые мысли?
EDIT: Я использую Babel.
Ответы
Ответ 1
Другой ответ неверный.
(теоретический) вопрос: почему в первом случае можно переопределить значение const?
Это фактически полностью не зависит от const
. С синтаксисом модуля ES6 вам не разрешается переназначать экспортируемое значение модуля, вне его. То же самое можно сказать и с export let FOO;
или export var FOO;
. Код внутри модуля - это единственное, что позволяет изменять экспорт.
Выполнение settings.FOO = 1
технически должно вызывать исключение, но большинство компиляторов в данный момент не обрабатывают этот конкретный край.
В качестве примера вы могли бы сделать
export var FOO;
export function setFoo(value){
FOO = value;
}
и учитывая это, это когда const
становится полезным, потому что он такой же, как и любой другой обычный JS-код. FOO = value
завершится с ошибкой, если он был объявлен как export const FOO
, поэтому, если ваш модуль экспортирует кучу констант, выполнение export const FOO = 1, FOO2 = 2;
- хороший способ экспортировать константы, это просто то, что Babel фактически не делает их неизменяемыми.
Ответ 2
В этом коде
import * as settings from './settings';
settings.FOO = 1;
В приведенном выше коде вы не назначаете напрямую постоянную переменную, а клонированную копию в settings
.
import * as settings from './settings';
^^^^^^^^^^^^
settings.FOO = 1;
Но это не так в следующем коде
import {FOO, BAR} from './settings'
FOO = 1;
Здесь FOO
и BAR
являются константами, и вы не можете назначить ему.