Модули 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 являются константами, и вы не можете назначить ему.