2016-10-25 2 views
7

У меня есть модуль под названием fooModule. Внутри этого модуля, я импортировать fooModule (сам):Как можно импортировать модуль es6?

import * as fooModule from './fooModule'; 

export function logFoo() { 
    console.log(fooModule) 
} 

Когда logFoo() называется, я могу видеть все экспорта в fooModule. Как это работает?

+1

Что вы хотите сделать? – anshuVersatile

+6

Импорт не является обязательным, а разрешение и исполнение являются отдельными. Сначала импорт анализируется и разрешается. К моменту выполнения кода все привязки уже разрешены. – Joseph

+2

Лучшая практика - не делать этого –

ответ

8

Циркулярные зависимости не являются проблемой для декларативных импорта/экспорта. В вашем случае, круг минимальной длины, хотя :-)

Решение состоит в том, что import не импортирует значения в переменную, но это делает переменная а ссылка к экспортируемой переменной. Посмотрите here на пример изменчивой переменной и на this question для точной терминологии.
И это одинаково для объектов пространства имен модулей - их свойства - это просто геттеры, которые разрешают фактическую экспортированную переменную.

Поэтому, когда ваш модуль будет загружен и оценены, выполняются следующие шаги:

  1. Источник статически анализировали на export и import деклараций построить график зависимостей
  2. создается Объем модуля
  3. Так как единственная зависимость вашего модуля сама по себе и что уже инициализируется, ее не нужно ждать
  4. Переменная fooModule создается и создается на основе объект с экспортированными именами модуля, которые, как известно, ["logFoo"]. Свойство fooModule.logFoo становится геттером, который будет оценивать переменную logFoo в области видимости модуля (если вы использовали export {A as B}, то fooModule.B разрешится до A, но в вашем случае оба иена будут совпадать).
  5. переменных декларации в рамках модуля создание переменного, в вашем случае logFoo и объявление функций инициализируются (т.е. logFoo получает назначение функции)
  6. Кода модуля выполняются (в вашем случае, ничего не происходит)

Теперь, когда вы вызываете logFoo в модуль, который импортирует его, fooModule будет ссылаться на пространство имен, которое содержит logFoo. No magic :-)

+0

Я полностью ценю все, что вы вложили в SO, но я не понимаю, как это использовать. Вы упомянули выше, это можно использовать, чтобы избежать дублирования кода, но когда это семантически имеет смысл для чего-то, чтобы зависеть от самого себя? – aaaaaa

+1

@aaaaaa Я могу только подумать о двух случаях: получить собственный объект пространства имен объектов (для динамического доступа к свойствам, для его экспорта по умолчанию и т. Д. - избегать создания такого объекта вручную) и доступа к собственному [анонимному экспорту по умолчанию] (HTTP: // StackOverflow.com/a/35225936/1048572) (когда по какой-то причине назвать его просто невозможно). – Bergi

Смежные вопросы