exports vs module.exports
发布于 12小时前 作者 russj 43 次浏览 来自 分享

Node.js 的 exports 和 module.exports 两者很容易给新手造成疑惑。这里希望能讲清楚它们的异同。

相同之处

exports 和 module.exports 并不是全局变量,而只是对各自的 module 可见。

它们指向同一个对象,其缺省初始值为空 {}。

如果 exports 和 module.exports 没有被重新赋值,这个对象就是将要输出的对象。

不同之处

module 是对当前模块的一个引用。真正输出的是 module.exports。

所以对 exports 直接赋值没有作用。而对 module.exports 直接赋值后,module.exports 就指向新的对象了,这个新的对象成为将要被输出的对象。

详细说明

exports 和 module.exports 指向的是同一个对象,所以给他们任何一个添加属性或方法,另外一个都会接收到变化,因为他们指向的是同一个对象。例如:

exports.afunc = function(){};
module.exports.name = "Wang";
console.log(exports);
console.log(module.exports);

后面两条语句的输出都是: { afunc: [Function], name: ‘Wang’ }

但是如果是对其中任何一个直接赋值,就会切断对最初对象的引用。

  • exports

例如给 exports 直接赋值,就切断了 exports 对之前其和 module.exports 一同指向的对象的引用,但是由于真正输出的是 module.exports 指向的对象,所以对 exports 赋值无效,比如在 ep.js 输入:

exports.name = "Wang";
var afunc = function(){};
exports = afunc; //注意对 require 无效
console.log(exports); //内部有效,输出 [Function]

在另外一个 me.js 输入:

var ep = require('./ep');
console.log(ep);//输出 {name: 'Wang'},不是 [Function]

要让 exports 输出,可以在 ep.js 加上

module.exports = exports; 

两者的 reference 关系再次建立。这样输出都是 [Function] 。

  • module.exports

如果给 module.exports 直接赋值,也切断了 exports 的引用,同样道理,因为真正输出的是 module.exports 指向的对象,所以新赋给 module.exports 的对象将被输出。例如把 ep.js 改为:

exports.name = "Li";
console.log(exports); //{name: 'Li'}
console.log(module.exports);//一样 {name: 'Li'}
module.exports = "Zhou";
console.log(exports); //还是 {name: 'Li'}
console.log(module.exports);//变为 Zhou

再次运行 me.js,输出 Zhou , 覆盖了之前的对象.

总结

真正输出总是 module.exports。如果两者同时出现或被修改,只有 module.exports 返回,exports 被忽略。

参考:

回到顶部