最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can an es6 module import itself? - Stack Overflow

programmeradmin0浏览0评论

I have a module called fooModule. Inside this module, I import fooModule (itself):

import * as fooModule from './fooModule';

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

When logFoo() is called, I can see all of the exports of the fooModule. How does this work?

I have a module called fooModule. Inside this module, I import fooModule (itself):

import * as fooModule from './fooModule';

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

When logFoo() is called, I can see all of the exports of the fooModule. How does this work?

Share Improve this question asked Oct 25, 2016 at 12:59 Mr. SpiceMr. Spice 1,5921 gold badge15 silver badges16 bronze badges 7
  • 1 what you want to do ? – anshuVersatile Commented Oct 25, 2016 at 13:03
  • 8 Imports aren't imperative and resolution and execution are separate. The imports are parsed and resolved first. By the time the code executes, all bindings are already resolved. – Joseph Commented Oct 25, 2016 at 13:05
  • 2 the best practice is to not do this – The Reason Commented Oct 25, 2016 at 13:06
  • 2 @TheReason Actually, importing your own module namespace object can be a useful thing that helps to avoid some duplicate code. – Bergi Commented Oct 25, 2016 at 14:14
  • 1 @trusktr If you need to lookup things by name, you typically use an object literal with the respective values as properties. If those happen to be exactly your exports, you can just use the module namespace object. – Bergi Commented Apr 28, 2018 at 8:16
 |  Show 2 more comments

1 Answer 1

Reset to default 21

Circular dependencies are no problem for declarative imports/exports. In your case, the circle is of minimal length though :-)

The solution is that an import does not import a value into a variable, but that it makes a variable a reference to the exported variable. Have a look here for an example of a mutable variable, and at this question for exact terminology.
And it's the same for module namespace objects - their properties are just getters that resolve to the actual exported variable.

So when your module is loaded and evaluated, the following steps occur:

  1. The source is statically analysed for export and import declarations to build a dependency graph
  2. The module scope is created
  3. Since the only dependency of your module is itself, and that already is getting initialised, it doesn't need to wait for it
  4. The fooModule variable is created and instantiated to an object with the exported names of the module, which are known to be ["logFoo"]. The fooModule.logFoo property becomes a getter that will evaluate to the logFoo variable in the module scope (if you had used export {A as B}, then fooModule.B would resolve to A, but in your case both names are the same).
  5. The variable declarations in the module scope create the variables, in your case logFoo, and function declarations are initialised (i.e. logFoo gets assigned the function)
  6. The module code is run (in your case, nothing happens)

Now when you call logFoo in a module that imports it, fooModule will refer to the namespace that contains logFoo. No magic :-)

发布评论

评论列表(0)

  1. 暂无评论