当有循环 require 调用时,模块在返回时可能尚未完成执行。

// a.js
const b = require("./b.js");
console.log(b);
exports.name = "a";
// b.js
const a = require("./a.js");
console.log(a);
exports.name = "b";

执行 node a.js , 会先后打印 {} { name: "b" }

a 模块加载了 b 模块 , b 模块又加载了 a 模块,他俩之间存在循环加载。

b 加载 a 的时候, a 模块还没导出 (exports) 呢!

为了防止无限循环,会将 a 导出对象的 未完成的副本 返回给 b 模块,在这个例子中, a 导出对象未完成的副本为一个空对象 {} ,所以会先打印 {}

紧接着 b 为导出对象设置了一个 name 属性, console.log(b) 语句把 b 的导出对象打印出来 { name: "b" }

如果我们在 a.js 中,再加一行代码这样的代码


 




// a.js
exports.age = 18;
const b = require("./b.js");
console.log(b);
exports.name = "a";

执行 node a.js , 会先后打印 { age: 18 } { name: "b" }

{ age: 18 } 即为 a 导出对象的 未完成的副本