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: '隐蔽真实想法, 一个真正的面壁者' }
来源: http://www.jianshu.com/p/886a714bf94c