From ReferenceError: can’t access lexical declaration ‘X’ before initialization – JavaScript | MDN, there is an example of invalid import:
a.js
(entry module):
import { b } from "./b.js";
export const a = 2;
b.js
:
import { a } from "./a.js";
console.log(a); // ReferenceError: Cannot access 'a' before initialization
export const b = 1;
MDN explains:
In this example, the imported variable
a
is accessed but is uninitialized, because the evaluation ofa.js
is blocked by the evaluation of the current moduleb.js
.
I understand this as importing a module means embedding the code of the module at the line of the import statement. That is, the a.js
becomes this at compile time:
console.log(a); // ReferenceError: Cannot access 'a' before initialization
const b = 1;
const a = 2;
Is this understanding correct? I don’t see it’s explained in import – JavaScript | MDN. I don’t know how to test this because reordering the lines in a.js
doesn’t change the result due to hoisting.
3
Answers
The code from an imported module is not simply embedded ("pasted"), but lives in a separate closure. Although this is surely an oversimplification, I compare the module with a function and the
export
statement with itsreturn
statement:Because the modules import each other, they cannot be loaded in any order: Pressing either button leads to a "Maximum call stack size exceeded" error.
But if you remove the unnecessary line (which only fills a local variable that is then discarded), it works.
You can use alternatively by making functions of
a and b.
Then call it up to the usage and then the updation of values will be done after callback,
No, the code is not embedded (copy/pasted) at the imported place. It is executed first. In your example you have a circular reference. The following will ocur (but not exactly, I simplified the concept):
a.js
is executed.a.js
tries to importb
fromb.js
.b.js
is executed.b.js
tries to importa
froma.js
.a.js
is already in memory because of circular reference and not executed again.b.js
continues to next line and tries to loga
.a
is not initialized, becausea.js
is still at line 1 (from the 2 bullet of this list).There are more than one way to do what you want depending on your needs. The following is one possible example:
a.js
b.js