node.js的学习之路|模块系统-基本规则,关于exports跟module.exports之间的引用

commjs的模块规范

  • 模块的作用域
  • 使用require方法来加载模块
  • 使用exports接口对象来导出模块中的成员
var 自定义变量名称 = require(’模块‘)
如果一个模块需要直接导出某个成员,而非采用挂载的方式,必须采用下面的这种方式
  • 两个作用
    • 执行被加载模块中的代码
    • 得到被加载模块中的exports导出接口对象
导出exports
  • node中的模块作用域,默认文件所有的成员只在当前文件模块有效
  • 对于希望可以被其他模块访问的成员,我们就需要把这些公开的成员都挂在到exports接口对象中就可以了
  • 导出多个成员:必须是对象
exports.a = 123 exports.b = 'hello' exports.c = function(){ console.log('ccc') } exports.d = { foo : bar }

  • 导出单个成员:(拿到的就是函数,字符串,如下)
function add (x,y){ return x+y } module.exports = add

【node.js的学习之路|模块系统-基本规则,关于exports跟module.exports之间的引用】以下情况会覆盖
module.exports = 'hello' // 以这个为准,后者会覆盖前者 module.exports =function (x,y){ return x+y }

也可以这样导出多个成员
module.exports= {items}

原理解析
  • 在node中,每个模块内部都有一个自己的module对象,该module中,有一个成员叫exports,也是一个对象,如果你需要对外导出成员,只需要把成员挂载到module.exports对象中,写module.exports.xxxx太麻烦,所以就简化
    也就是说在模块中还有这样一句隐藏代码:
var exports = module.exports
但是exports只是module.exports的一个引用,所以当我们赋值给exports的时候,哪怕是个空对象,从此也跟module.exports对象没有关系,最后return的是module.exports对象,所以给exports重新赋值是不管用的,一旦重新赋值就丢失了跟module.exports的引用关系了,就无法再往里面添加成员了,所以挂载的时候要么exports.xxx = xxx,要么module.exports.xxx= xxx

    推荐阅读