NodeJS中 export 与 module.exports 的关系

454 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

引子

今天来讲一下NodeJS中 module.exports 是什么以及它与exports的区别

其实在最初的 CommonJS 中是没有module.exports这个概念的,为了实现模块的导出就添加了;但有同学可能会问,不是exports也可以实现吗?其实两者性质是不一样的;

由于Node中使用的是Module的类,每一个模块都是Module的一个实例,也就是 module 其实在上文中,所以在Node中真正用于导出的其实根本不是exports,而是 module.exports, 因为module才是导出的真正实现者;

并且 module.exports 在最顶层赋值, 在其他文件中的 require 会指向 module.exports,因为module对象的 exports 属性是 exports 对象的一个引用

🥚那他们的区别是什么,该在什么场景下去使用?

我们通过下图来加深理解:

image-20220613151010941

其实本意就是默认将 Module.exports指向 exports,当Module.exports单独导出时,exports 就失去它的作用了

让我们来证实一下,举一个栗子:

有两个文件分别为: index.js(主文件) 与 bar.js(模块文件)

bar.js文件

 const name = "shrimpsss";
 const hobby = ["singing", "dancing", "reading"];
 function sayHello(name) {
     console.log( "Hello , "  + name);
 };
 
 // 先改 exports
 exports.name = name;
 exports.sayHello = sayHello;
 exports.hobby = hobby;
 
 // 后改 module.exports
 module.exports = {
     name: "True",
     hobby,
     sayHello
 };

index.js文件

 const { name, sayHello, hobby } = require('./bar.js');
 console.log(name); 
 hobby[1] = 'basketball';
 setTimeout(() => {
     sayHello(name);
     console.log(hobby);
 }, 1000);

这样的打印结果为True ,有的同学可能会说:"那你把module.exports放在前面 exports 后面 ,那 name 打印的肯定是True"

其实打印的都是一样的结果,name一样为True, 如下所示:

image-20220613154702159

内部执行过程

如果还不了解的话,我们再了看看内部的执行过程,应该就会很清晰了

image-20220613155842757

这样应该就清晰明了,用于Node中模块是通过 Module.exports 导出的,当它不再独自导出,指向 exports 时, exports 就失去他的作用了

总结:

  1. 当前文件下的 module.export 默认指向 export, 修改 export 会影响到其他文件的 require 以及当前文件下的 module.exports (如果不使用 module.exports 以对象的形式导出的话)
  2. 当前文件下的 module.exports 和 exports 是同一个对象
  3. 若在主模块中修改导入模块中的常量会报错,但是修改引用值是可以的

最后如果本文对于本文有疑惑,还请指导勘正 (●'◡'●)