node.js中,每个js文件都可以当成一个模块,每个模块中,都隐含了一个名为module
的对象,module
对象中有一个exports
属性,这个属性的功能是将模块中的变量暴露给其他模块调用。
console.log(typeof module)
console.log(module)
结果:
object
Module {
id: '.',
exports: {},
parent: null,
...
}
当模块被引用时,如果没有使用exports
暴露变量,其他模块就不能使用其数据。正所谓,你能得到我的人,却得不到我的心...
13.js
require('./14')
console.log(name)
14.js
let name = '叶文洁'
执行会报找不到name
变量
☁ 01 [master] ⚡ node 13.js
console.log(name)
^
ReferenceError: name is not defined
接下来我们使用module.exports
暴露变量
15.js
let moduleExports = require('./16')
console.log(moduleExports)
console.log(moduleExports.name)
let name = '罗辑'
moduleExports.introduce(name)
16.js
let name = '叶文洁'
module.exports.name = name
module.exports.introduce = function (name) {
console.log('请介绍' + name + '的人物生平')
}
运行结果:
☁ 01 [master] ⚡ node 15.js
{ name: '叶文洁', introduce: [Function] }
叶文洁
请介绍罗辑的人物生平
以上的写法比较繁琐,每次要暴露变量,都需要写module.exports
,在以懒惰为美德的程序员看来,这是不能忍受的。因此node.js提供了一个变量exports
作为module.exports
的引用
16.js
也可以写成:
let name = '叶文洁'
// exports 是 module.exports 的引用
console.log(exports === module.exports) // true
exports.name = name
exports.introduce = function (name) {
console.log('请介绍' + name + '的人物生平')
}
接下来,问题来了,如果我们想将模块暴露的变量重新赋值呢?默认情况下,exports
是一个对象,假设我们的需求是要得到一个字符串。要怎么弄?
也许你觉得这个很简单,直接给exports
重新赋值就可以了。我们来试下:
17.js
let moduleExport = require('./18')
console.log(moduleExport)
18.js
let name = '章北海'
exports = name
执行结果:
☁ 01 [master] ⚡ node 17.js
{}
为何不是我们期待的结果?让我们将exports
换为module.exports
试下:
18.js
let name = '章北海'
module.exports = name
结果:
☁ 01 [master] ⚡ node 17.js
章北海
既然exports === module.exports
,那么为何修改exports
不起作用?
原因是,exports
是module.exports
的引用,当exports
被重新赋值时,并不会影响到module.exports
的值,而模块返回的是module.exports
,因而只有给module.exports
重新赋值,才起作用
来个更复杂点的例子:
18.js
let name = '章北海'
module.exports = name
exports = {}
exports.age = 10
module.exports = {}
module.exports.skill = '隐蔽真实想法,一个真正的面壁者'
结果:
☁ 01 [master] ⚡ node 17.js
{ skill: '隐蔽真实想法,一个真正的面壁者' }
网友评论