Node.js 中 exports 和 module.exports 的区别

240 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

Node.js 中 exports 和 module.exports 的区别

  1.  每个模块中都有一个 module 对象
  2. module 对象中有一个 exports 对象
  3. 可以把需要导出的成员都挂载到 module.exports 接口对象中
  4. 即以:moudle.exports.xxx = xxx 的方式
  5. 但是如果每次都以 moudle.exports.xxx = xxx 的方式会很麻烦,因为点儿的太多了
  6. 所以 Node 为了方便,同时在每一个模块中又都提供了一个成员叫:exports
  7. 因为exports === module.exports 结果为  true
  8. 所以对于:moudle.exports.xxx = xxx 的方式 完全可以:expots.xxx = xxx
  9. 当一个模块需要导出单个成员的时候,这个时候必须使用:module.exports = xxx 的方式
  10. 不要使用 exports = xxx 不管用
  11. 因为每个模块最终向外 return 的是 module.exports
  12. exports 只是 module.exports 的一个引用
  13. 所以即便你为 exports = xx 重新赋值,也不会影响 module.exports
  14. 但是有一种赋值方式比较特殊:exports = module.exports 这个用来重新建立引用关系的
exports.foo = 'bar'  // {foo: bar}

module.exports.a = 123  // {foo: bar, a: 123}

// exports !== module.exports
// 最终 return 的是 module.exports
// 所以无论你 exports 中的成员是什么都没用
// exports 冲洗赋值与 module.exports 断开了联系
exports = {
  a: 456
}

module.exports.foo = 'haha'  // {foo: 'haha', a: 123}

// 没关系,混淆你的   exports再赋值已经对 module.exports 没有影响
exports.c = 456  

// 重新建立了和 module.exports 之间的引用关系了
exports = module.exports

// 由于在上面建立了引用关系,所以这里是生效的
exports.a = 789  // {foo: 'haha', a: 789}

// 前面再牛逼,在这里都全部推翻了,重新赋值
// 最终得到的是 Function  因为最后 return 的是 module.exports
module.exports = function () {
  console.log('hello')   // 因此输出为  hello
}

// 真正去使用的时候:
//    导出多个成员:exports.xxx = xxx
//    导出多个成员也可以:module.exports = {
//                        }
//    导出单个成员:module.exports
// 谁来 require 我,谁就得到 module.exports
// 默认在代码的最后有一句:
// 一定要记住,最后 return 的是 module.exports
// 不是 exports
// 所以你给 exports 重新赋值不管用,
// return module.exports