NodeJs:module.exports 和 exports 解惑
背景
NodeJs引入了模块化机制,只有显式声明为导出的对象才会被外部访问到,导出语法有两种:module.exports 和 exports,这两种到底有何区别呢?这是我今天试验的目的。
试验
材料
module1.js
1 this.hi = function () { 2 console.log('hi in module1'); 3 }; 4 5 exports.say = function () { 6 console.log('haha in module1'); 7 }; 8 9 module.exports.hello = function () { 10 console.log('hello in module1'); 11 };
module2.js
1 module.exports.say = function() { 2 console.log('haha in module2'); 3 }; 4 5 module.exports.hi = function() { 6 console.log('hi in module2'); 7 }; 8 9 module.exports.hello = function () { 10 console.log('hello in module2'); 11 };
module3.js
1 console.log('exports == module.exports?,' + (exports == module.exports)); 2 console.log('this == module.exports?,' + (this == module.exports)); 3 4 this.hi = function () { 5 console.log('hi in module3'); 6 }; 7 8 exports.say = function () { 9 console.log('haha in module3'); 10 }; 11 12 module.exports = {}; 13 14 console.log('exports == module.exports?,' + (exports == module.exports)); 15 console.log('this == module.exports?,' + (this == module.exports)); 16 17 module.exports.hello = function () { 18 console.log('hello in module3'); 19 };
exports_test.js
1 var module1 = require('./module1.js'); 2 module1.hi(); 3 module1.say(); 4 module1.hello(); 5 6 console.log('\n'); 7 8 var module2 = require('./module2.js'); 9 module2.hi(); 10 module2.say(); 11 module2.hello(); 12 13 console.log('\n'); 14 15 var module3 = require('./module3.js'); 16 console.log('module3.hi === undefined?,' + (module3.hi === undefined)); 17 console.log('module3.say === undefined?,' + (module3.say === undefined)); 18 module3.hello();
输出
1 hi in module1 2 haha in module1 3 hello in module1 4 5 6 hi in module2 7 haha in module2 8 hello in module2 9 10 11 exports == module.exports?,true 12 this == module.exports?,true 13 exports == module.exports?,false 14 this == module.exports?,false 15 module3.hi === undefined?,true 16 module3.say === undefined?,true 17 hello in module3
结论
- exports默认和module.exports指向同一个空对象。
- 最终导出的对象是module.exports指向的对象。
- 由1和2可以推论出,如果运行时让exports、this和module.exports指向不同的对象,只有module.exports指向的对象才回被导出。
- 由1和2可以推论出,用exports只能导出对象,用module.exports可以导出任何类型。