exports和module.exports的区别

请牢记一条原则:无论使用 exports 暴露成员,或是 module.exports 暴露成员,最终暴露的结果,都是以 module.exports 所指向的对象为准。
1.module 对象

看一下 module对象长什么样子
module 对象

2.module.exports 和 exports 的联系
  • 在 module 对象中,包含 exports 属性,而我们就是通过这个属性(module.exports),向外暴露(共享)成员的。
  • exports 是 node 为了简化向外共享成员的代码,提供的一个新方式,在默认情况下,exports 和 module.exports 指向的是同一个对象(为了不混淆,你可以理解为 exports 是 module.exports 对象地址的一个引用,exports 本质是一个变量)。
3.module.exports 和 exports 的区别
  • 两者没有区别,是全等的
4.module.exports 和 exports 的使用注意点(略长,但是认真看完,理解一下就懂了)
一、不恰当的使用方法:exports = xxx;
4.1 论述:
  1. 在使用 module.exports 时,我们可以将某一个对象赋值给 module.exports(module.exports = Object),也可以为 module.exports 挂载新属性( module.exports.name = ‘zs’),这些都没有问题,你都可以在引用的文件中拿到修改后的模块成员(module.exports 所指的对象)。
  2. 但是,如果你将某一对象或某一变量直接赋值给了 exports(例如:const project = ‘张三’; exports = project; ),那么你在引用的文件中只能拿到一个 {}。
  3. 原因是因为 exports 在默认情况下是指向 module.exports 对象的引用,如果为 exports 赋值了,那么也就是说 exports 不再指向 module.exports 所指的对象的地址,而我们向外共享成员的最终结果是 module.exports 所指的对象,如此便会导致错误。
4.2 代码展示:尝试使用 exports 直接向外共享对象(共享其他数据类型结果一致)

定义两个文件,做一下代码展示与说明

  • exports.js 文件
// 定义一个对象
const porject = {
    name: 'zs',
    age: 20
};
// 尝试使用 exports 对象共享 project 对象
exports = porject;
  • index.js 文件
// 导入 exports 模块,试图拿到 exports 中的 project 对象
const ex = require('./exports');
// 打印 exports.js 中向外暴露的对象
console.log(ex);
  • 打印结果
    在这里插入图片描述
4.3 重要结论:module.exports 和 exports 同指一个对象,但是最终暴露结果以 module.exports 的为准,上面的代码中,exports 改变了指向,而我们又没有为 module.exports 挂载任何的属性或方法,所以就拿到了空对象。

画图举例
刚开始 module.exports 和 exports 指向同一个对象
在这里插入图片描述

然后 exports 指向了一个新对象
在这里插入图片描述

但我们向外暴露时,是以 module.exports 为标准的,也就是向外暴露的是上图中的“原对象”,而不是“新对象”,在上述代码中,我们没有对原对象做任何操作,原对象是没有值的,所以我们导入了 exports.js 之后,得到的是一个空对象。

二、正确的使用方法:exports.xxx = xxx;
4.4 论述:

1.我们可以为 exports 挂载新的属性或方法(exports.name = ‘张三’),向外共享成员也能够拿到想要的修改后的对象

4.5 代码展示:尝试使用 exports 挂载成员后,向外共享成员。

定义两个文件,做一下代码展示与说明

  • exports.js 文件
// 尝试使用 exports 对象挂载 str 属性后,向外共享
exports.str = '张三';
  • index.js 文件
// 导入 exports 模块
const ex = require('./exports');
// 打印 exports.js 中向外暴露的成员
console.log(ex);
  • 打印结果
    在这里插入图片描述
4.6 重要结论:使用 exports 挂载成员的方式不会令 exports 不再指向 module.exports 所指的对象。上述代码中的 exports.str = ‘张三’; 相当于 module.exports.str = ‘张三’;

画图举例
刚开始 module.exports 和 exports 指向同一个对象
在这里插入图片描述
然后我们为 exports 挂载了一个 str 的属性
在这里插入图片描述
可以清楚得知道,exports.str = ‘张三’; 的操作,只是为 exports 所指对象,添加一个新属性,这并不会使 exports 指向一个新的地址(对象);所以我们可以成功的拿到 { str:‘张三’ };

5. 总结

这种 exports.xxx = xxx; 的使用方法才是恰当的,才能够保证 exports === module.exports。

补充:看完还是没有理解的话,给我留言哈!

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值