重新激活这里,现在要进行一个 21-day-push plan,所以估计会很经常更新这里,也准备把博客迁移到一个 amazon 的服务器上,折腾一下后台 nodejs、python 或者 ruby or whatever。

这些都是后话,这篇要记录一下 nodejs old topic:module.exports 和 exports 的区别。

如果想直接知道我的结论,看这一段就可以了
  1. 如果想要暴露一个且只有一个对象,那么就使用 module.exports = 你的对象名
  2. 如果想要暴露的是各种方法,那么使用 exports.方法名 = 你的方法名
  3. 如果已经使用了 module.exports = xxx,那么是没有办法再使用 exports.xxx=xxx
好的,现在来解释

首先这篇文章中说了一个观点:

If you want your module to be of a specific object type, use module.exports; if you want your module to be a typical module instance, use exports.

这个意思呢,就是说如果想要创建一个全新的 object,换句话说就是一个全新的数据类型(类似于 c 的struct),那么应该用 module.exports;如果是想提供一个模块实例,那么就使用 exports

讲真,对于exports 的使用我还是摸不着头脑,但是好歹 module.exports 的用法我算是明白了,看了 npm 上一些 lib 的代码,也可以发现大部分情况下,大家用的还是 module.exports

module.exports 的用法其实是在模块内部用原型链实现对象的方法的。这样在调用对象的时候,可以通过原型链的方式,调用到它的方法。ok,这边是我的理论理解,明天要重写一下代码验证这一点。而且想要用 ES6 的方法重写它。

exports 其实是 module 的一个属性,如果 module.exports 被使用了,那么再使用 exports.xxx 的时候,就会被认为这是一个全新的对象,调用的这样的方法会报 undefined 错误。

ok,也就是说这两个东西不能同时使用啦。

好的,如果一定要使用的话,就这么用:

module.exports = {
  func1: function(){...},
  func2: function(){...}
};

// 以上等价于👇
exports.func1 = function(){...};
exports.func2 = function(){....};
        

或者这么使用

// 然而我并不明白干嘛要这么写,用 module.exports 或者 exports 二者之一就好啦
var exports = module.exports = {...};

另外,看 API 中还有一些额外的信息:

module.exports 不能写在 setTimeout 或者 setInterval 之类的里面,模块的导出是即时的。

然后官方说了句特别简单粗暴直白好懂的话:

As a guideline, if the relationship between exports and module.exports seems like magic to you, ignore exports and only use module.exports.,

大白话就是,要是你不知道要用啥,那就用 moduel.exports。[doge笑]

好吧,突然发现博客是很有意义的事情,让我知道了,特么原来还有这么多知识漏洞要补。