импорт es6 как представление только для чтения

Нет подробного объяснения того, что именно импорт и экспорт es6 делают под капотом. Кто-то описывает импорт как представление только для чтения. Проверьте код ниже:

// lib/counter.js
export let counter = 1;

export function increment() {
  counter++;
}

export function decrement() {
  counter--;
}


// src/main.js
import * as counter from '../../counter';

console.log(counter.counter); // 1
counter.increment();
console..log(counter.counter); // 2

Мой вопрос: если два модуля импортируют один и тот же модуль счетчика, а первый модуль увеличивает счетчик, будет ли второй модуль также видеть счетчик как увеличенный? Что под капотом делают «импорт» и «экспорт»? В каком контексте выполняется функция приращения? Что такое переменный объект функции приращения?

// lib/counter.js
export let counter = 1;

export function increment() {
  counter++;
}

export function decrement() {
  counter--;
}


// src/main1.js
import * as counter from '../../counter';

console.log(counter.counter); // 1
counter.increment();
console..log(counter.counter); // 2


// src/main2.js
import * as counter from '../../counter';
console.log(counter.counter); // what is the result of this, 1 or 2?

Мне кажется, что «экспорт» создает глобальный объект, к которому могут обращаться разные модули, и устанавливает контекст экспортируемой функции для этого объекта. Если это так, то дизайн зашит за меня, потому что модули не знают, что делают другие модули. Если два модуля импортируют один и тот же модуль (счетчик), один модуль вызывает функцию увеличения (пример выше), которая вызывает изменение значения (счетчика), а другой модуль этого не знает.


person Jinxin Ni    schedule 27.06.2016    source источник


Ответы (2)


См. раздел 16.3.5 здесь

Как уже упоминалось:

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

//------ lib.js ------
export let counter = 3;
export function incCounter() {
    counter++;
}

//------ main.js ------
import { counter, incCounter } from './lib';

// The imported value `counter` is live
console.log(counter); // 3
incCounter();
console.log(counter); // 4

Как это работает внутри, объясняется в более позднем разделе.

Импорт в виде представлений имеет следующие преимущества:

  • Они включают циклические зависимости даже для неквалифицированного импорта.
  • Квалифицированный и неквалифицированный импорт работают одинаково (оба являются косвенными).
  • Вы можете разделить код на несколько модулей, и он продолжит работать (пока вы не попытаетесь изменить значения импорта).
person JoeTidee    schedule 24.05.2017
comment
не могли бы вы привести примеры, чтобы было понятнее, если это возможно - person agent47; 08.03.2018

Ответ зависит от того, какой у вас входной модуль. Например, если вы определяете входной модуль как:

// index.js
import "./main1";
import "./main2";

Тогда вывод:

1 // from main1
2 // from main1
2 // from main2

Модулям ES6 разрешено удерживать состояние, но им не разрешается напрямую манипулировать состоянием других модулей. Сам модуль может предоставлять функцию-модификатор (например, ваш метод increment).

Если вы хотите немного поэкспериментировать, rollupjs есть хорошая онлайн-демонстрация, которая показывает, как должны работать стандартные операции импорта и экспорта.

person Tamas Hegedus    schedule 27.06.2016
comment
Если модули имеют состояние. Как разные разработчики, использующие один и тот же модуль, могут остерегаться этого состояния. Например, два человека разрабатывают два разных модуля, используя один и тот же модуль, и они не знают, как другой разработчик изменит состояние этого общего модуля. - person Jinxin Ni; 27.06.2016
comment
@JinxinNi: если модуль должен использоваться несколькими вещами, он не должен иметь состояния. Так просто, как, что. - person Bergi; 27.06.2016
comment
@JinxinNi Берги прав, модули могут иметь состояние, но полагаться на него, безусловно, плохая практика. Причина именно в том, что вы указали. - person Tamas Hegedus; 27.06.2016