NodeJS中的exports和module.exports的区别

来源:互联网 发布:地毯胶如何清除 知乎 编辑:程序博客网 时间:2024/06/05 03:33

从一开始接触nodejs的时候就开始对模块里面的代码很感兴趣。看多了之后,发现一个问题,就是有一些地方导出是这样的:

//module1.jsmodule.exports = Object;function Object () {  //constructor}

有一些地方导出是这样的:

//module2.js//function 1exports.func1 = function () {  //do something}//function2exports.func2 = function () {  //do something}

还有一些地方导出是这样的:

//module3exports = module.exports = Object;function Object() {  //constructor}

这就让人很费解了。为什么要有这么多的导出的方式。这些方式之间有什么区别。在什么时候用什么方式呢。

在这之前,先了解一下module 和 exports 到底是什么东西。直接看代码:

//testmodule.jsconsole.log(module.exports === exports); //true

可以看出,其实module.exports和exports其实是同一个东西。它们的定义其实是类似这样的:

var theModule = {  exports: {}};(function(module, exports, require) {  // Your module code goes here})(theModule, theModule.exports, theRequireFunction);

也就是说,在初始化的时候,module.exports和exports指向同一个空对象:
这里写图片描述
所以,无论是给exports的原型还是module.exports的原型加上属性,都会给它们指向的空对象加上属性。比如:

module.exports.name = 'shi zhangfan';exports.age = 26;

那么这个模块导出的对象如下:

{ name: 'shi zhangfan', age: 26 }

但是,使用module.exports和exports还是有区别的!
使用module.exports的话,那么exports也会指向这个对象,但是如果使用exports.foo的话,那么exports.foo指向了新对象,但是module.exports还是指向原来的空对象,就像这样:
这里写图片描述
所以,这就是为什么要用到下面这种形式了:

exports = module.exports = function () {/* ... */}

这样的话,module.exports和exports依然会指向相同的对象。