在Node.js模块化中,首先了解模块化作用域。
- 和函数作用域类似,在自定义模块中,定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域。
- 可以防止 全局作用域的变量污染问题。如果使用 script src='index.js’的方式引用,会把里面的变量都放到window中。
- 如果引用了两个js文件中,有相同的变量,这是会造成覆盖。
这个时候就需要向外共享模块作用域的成员
exports
和 moudle.exports
module.exports 对象
- 在自定义模块中,可以使用 module.exports对象,将模块内的成员共享出去,供外界使用。外界通过require() 引入模块时,得到的返回值就是module.exports 对象
- 默认情况下,module.exports是一个空对象。
exports 对象
- 作用和module.exports一样。module.exports===exports,默认情况下,exports 和 module.exports 指向同一个对象,
最终共享的结果,还是以module.exports为准。
注意:使用require导入的返回的对象,永远是指向module.exports为准
一、只有 moudle.exports 的时候
- 01的Js文件里面的代码:
module.exports.sex = 1
module.exports.name = '张三'
在06的Js中require导入,然后输出
const fmodule = require('./01什么是http模块')
console.log(fmodule);
node 运行06文件。
它的理论,就是在得到的结果就是在module.exports中添加需要对外暴露的属性。
- 那如果是这样的代码呢?
module.exports.sex = 1
module.exports.name = '张三'
module.exports = {
name: '王五'
}
最后得到的结果,只有 王五。
虽然在前面存放了sex和name的属性。但是后面
module.exports = {
name: ‘王五’
}
module.exports指向了另一个新开辟的内存地址。不再指向以前的地址,所以,前面的name=‘张三’ sex=1 自然就不作数了,因为他们先存进去,但是对外暴露的地址已经不再指向它们。
- 换一个位置看看呢?
module.exports = {
name: '王五'
}
module.exports.sex = 1
module.exports.name = '张三'
最后得到的值:
先在一开始就开辟一个空间,存了 name=‘王五’,
后来又在这个里面存了其他属性,由于又存了一次name,所以会覆盖前面的值。
- 这样子换位置嘞?
module.exports.sex = 1
module.exports = {
name: '王五'
}
module.exports.name = '张三'
结果就是
name = ‘张三’
二、 moudle.exports 和exports同时存在的时候
这时,就始终记住——使用require导入得到的对象,永远是指向module.exports为准
- 一开始和谐共处,大家都在一个内存空间
module.exports.sex = 1
module.exports.name = '张三'
exports.username = 'xx'
- 后来module.exports不和exports一起了,另外指向了一处地址
module.exports = {
age: 18
}
module.exports.sex = 1
module.exports.name = '张三'
exports.username = 'xx'
但是最后对外暴露的,是以module.exports 为准的。所以,exports 对象里的就不作数了。
- 那万一是exports ’离家出走‘呢?
module.exports.sex = 1
module.exports.name = '张三'
exports = {
text: 'hi'
}
可想而知,结果是 sex 和name 。因为exports 和module.exports不再是指向听一个地址了。