Why does this code fragment referenced by node.js loop work normally?

  node.js, question

Module a code:

Log ('start loading module a');
 var b = require('./b.js');
 console.log('in a, b is ', b);
 exports.func = function() {
 Log ('call to module a succeeded');
 Log ('module a loaded');

Module b code:

Log ('start loading module b');
 var A = require('./a.js');
 console.log('in b, a is ', A);
 exports.callAmodule = function() {
 Log ('module b loaded');

Run the following code, first load module A and make circular reference:

var a = require('./a.js');
 var b = require('./b.js');

The operation results are as follows:

Start loading module a.
 Start loading module b
 in b, a is  {}
 Module b loaded
 in a, b is  { callAmodule: [Function] }
 Module a loaded
 Call to module a succeeded

The two modules generate circular references. When executing:A in module b is not fully loaded.. butcallAmoduleThe method successfully implemented the method of module A,This is not in line with my expectation., another similar circular reference, did cause problems, is in line with my expected code see:http://selfcontained.us/2012/ …

It is not clear why two similar circular reference codes have completely different results.

If you change the code of module A inside to the following, the expected error will appear:

module.exports = {
 func: function () {
 Log ('call to module a succeeded');

Understanding this requires understanding the difference between exports and module.exports:

  1. Exports is a reference to the module.exports

  2. Exports initial value is an empty object {}, module.exports initial value is {}

  3. Require () returns module.exports instead of exports

Before module a is loaded, module b is loaded. at this time, module.exports of module a returned by var a = require(‘./a.js’) is {}. After the loading of module b is completed, continue to return to module a to complete the loading of module a.

If the method is defined by exports.func in module A inside, the func method will be dynamically added to module.exports of module A. There is no problem when the method is called by A.func ().

If the method is defined by module.exports = {func: …} in module A inside, since var a = require(‘./a.js’) has returned module A module’s module.exports is {}, After loading module b, continuing to load module a will not change the value exported by module a to {}. therefore, when calling A.func (), a TypeError: A.func is not a function error will appear.