关于nodejs中module.exports和exports的关系,其实网上有许多文章有解释,但看完之后还是理解得不够深入。
经过代码测试之后,我才彻底明白。
因此我比较喜欢用代码说明问题。
module.exports和exports是怎样的存在
QQ截图20171111230425.png
从代码可以看出,在node环境中。 js文件运行时,会有一个默认的module对象,而exports是module.exports的一个引用,当给exports添加属性时,module.exports也跟随改变。
而当使用如 module.exports={a:'ddd'} 的形式定义输出时,module.exports就指向了一个新的引用,但exports仍然是原来的引用,因此是一个空对象。
QQ截图20171111231528.png
用module.exports导出就可以了,为什么要增加一个exports?
这点我觉得是想写代码方便一点。
诚然,我们可以把所有内容放到一个obj中,用一个module.exports=obj就可以导出。但有时我们希望书写更加自由。可以每写一个方法输出一个。不至于都挤在一堆。
例如:
QQ截图20171111232805.png
但是这样子会写很多个module.exports,不如再定义一个var exports=module.exports, 于是就有了exports的存在。
为什么模块定义要写exports=module.exports=xxx?
当使用module.exports=xxx定义之后,module.exports与exports就指向了不同的对象。但最终模块被引入时,使用的是module.exports的内容。
例如:
QQ截图20171111233739.png
这里定义了一个b.js,其中引入a.js模块,引入后a.js模块定义的exports.b并没有导出,原因是exports与module.exports指向了不同对象。
但如果使用exports=module.exports=xxx ,使exports和module.exports重新统一指向,最后exports.b就会被导出。
但要注意的是。xxx必须是一个能添加属性的对象,可以是object,可以是function,甚至可以是数组,但绝不能是基本类型
QQ截图20171111234140.png
总结
之所以要在module.exports之外再定义一个exports,是因为希望写代码时导出内容更灵活。
而由于存在module.exports赋值后指向变更的问题,使module.exports和exports 两种形式混用时存在漏洞。用exports=module.exports=xxx可以避免此问题。
如果模块中只用exports或只用module.exports导出对象,其实是没有必要这样写的。
当然,如果要统一作为代码规范,还是推荐这种严谨的写法。
作者:小飞牛牛
链接:https://www.jianshu.com/p/1e30c4f5d89e