CommonJS递归导入很奇怪

Strange thing with CommonJS recursive importing

本文关键字:导入 递归 CommonJS      更新时间:2023-09-26

我不知道问题在哪里:在JavaScript VM或在其他东西…但是在这个简单的程序

m.js

console.log("main", require("./m1"));

m1.js

var M = require('./m2');
exports.m = {
    m2: M.m,
    test: "m1"
}

m2.js

var M = require('./m1');
exports.m = {
    m1: M.m,
    test: "m2"
}
console.log("m2", M);
setTimeout(function() {
    console.log("m2 nexttick", M);
}, 0);

我得到一个奇怪的输出。

m2 {}
main { m: { m2: { m1: undefined, test: 'm2' }, test: 'm1' } }
m2 nexttick { m: { m2: { m1: undefined, test: 'm2' }, test: 'm1' } }

有人能解释一下吗?为什么要异步填充对象?

下面是require函数的伪版本,以说明为什么会发生这种情况。

当你在一个模块上调用require时,它会在缓存中创建一个空模块。然后,它尝试对模块求值。如果您需要另一个模块,而另一个模块require是原始模块,则它将获得空模块,因为第一个模块尚未完成对的求值。

我在这里的回答非常有限,但是你可以找到关于循环依赖的完整文章。

var cache = { };
function require(moduleName) {
    if ( cache.hasOwnProperty(moduleName) )
        return cache[moduleName]
    cache[moduleName] = undefined;
    cache[moduleName] = evaluate( moduleName );
}