有很多同学对node中exports和module.exports两种导出方式的区别和关系不是很了解,经常混淆.其实了解和区别两种方式从内存封面来解释会更加简单,接下来就让我们从内存的角度来认识一下exports和module.exports吧!
下面aaa.js模块中我们分别用方法一和方法二导出,达到的效果是一样的,且发现module.exports和exports是全等的,这是因为在内存中exports和module对象中的exports属性指向的是同一个对象
const name = 'jade'
const age = 18
// 方法一
exports.name = name
exports.age = age
// 方法二
module.exports.name = name
module.exports.age = age
console.log(module.exports === exports) // 返回true
但是以上的两种导出方式都是不怎么常用的,我们往往采用以下方法三的方式导出会更多一些
const name = '张三'
const age = 18
// 方法三
module.exports = {
name,
age
}
接下来我们从以上的模块中再加两行,得到以下代码,大家可以先思考一下,以下的这个模块导出的name属性是张三,还是李四,还是王五?
const name = '张三'
const age = 18
exports.name = '李四'
// 方法三
module.exports = {
name,
age
}
exports.name = '王五'
答案是张三,为什么呢? 因为方法三等同于将module.exports指向了一个全新的对象,此时module.exports和exports指向的对象就不是同一个了,而node导出的对象本质是module中exports属性指向的对象,因此一个模块在使用方法三之后exports再做任何导出都没有意义了.
总结:
node导出的对象本质是module中exports属性指向的对象,那可能有人要问了,那exports还有什么用?为什么node导出的真正实现者是module却还要设计一个exports?那是因为node想要使用commonjs的规范,在commonjs规范中导出就是使用exports,所以为了符合commonjs的规范node将module.exports和exports设计指向的是同一个对象.这样就可以符合commonjs的规范了.