持续创作,加速成长!这是我参与「掘金日新计划 · 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 对象的一个引用
🥚那他们的区别是什么,该在什么场景下去使用?
我们通过下图来加深理解:
其实本意就是默认将 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, 如下所示:
内部执行过程
如果还不了解的话,我们再了看看内部的执行过程,应该就会很清晰了
这样应该就清晰明了,用于Node中模块是通过 Module.exports 导出的,当它不再独自导出,指向 exports 时, exports 就失去他的作用了
总结:
- 当前文件下的 module.export 默认指向 export, 修改 export 会影响到其他文件的 require 以及当前文件下的 module.exports (如果不使用 module.exports 以对象的形式导出的话)
- 当前文件下的 module.exports 和 exports 是同一个对象
- 若在主模块中修改导入模块中的常量会报错,但是修改引用值是可以的
最后如果本文对于本文有疑惑,还请指导勘正 (●'◡'●)