来自 ReferenceError:在初始化之前无法访问词法声明 'X' - JavaScript | MDN,有一个无效导入的例子:
a.js
(入门模块):
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 解释:
在此示例中,导入的变量
已被访问但未初始化,因为a
的计算被当前模块a.js
的计算所阻止。b.js
我将其理解为导入模块意味着将模块的代码嵌入到导入语句的行中。也就是说,
a.js
在编译时变成了这样:
console.log(a); // ReferenceError: Cannot access 'a' before initialization
const b = 1;
const a = 2;
这种理解正确吗?我没有看到 import - JavaScript | 中对此进行了解释MDN。我不知道如何测试这个,因为重新排序
a.js
中的行不会因为 提升而改变结果。
导入模块中的代码不是简单地嵌入(“粘贴”),而是存在于单独的闭包中。虽然这肯定过于简单化,但我将模块与函数以及
export
语句与其 return
语句进行了比较:
function a_js() {
var b = b_js(); // unnecessary line
return 2;
}
function b_js() {
var a = a_js();
console.log(a);
return 1;
}
<button onclick="a_js()">import a.js</button>
<button onclick="b_js()">import b.js</button>
由于模块相互导入,因此无法以任何顺序加载:按任一按钮都会导致“超出最大调用堆栈大小”错误。
但是如果你删除不必要的行(它只填充一个局部变量,然后被丢弃),它就可以工作。