Nodejs导出和module.exports:为什么我们需要导出?

当我读到关于这个话题的另一个问题的一些答案时:

我(猜)了解什么出口和module.exports是,以及如何使用它们!

我不明白的是为什么我们需要出口 ,因为我们可以使用module.exports完全解决问题。 此外,如果我认为它很好: 出口有潜力造成错误。

例如:

// feature.js function Person(name) { this.name = name; this.greet = function() { console.log('Hi, my name is ' + this.name); } } module.exports = Person; // app.js var Person = require(./feature); var Aron = new Person('Aron'); Aron.greet(); // Hi, my name is Aron 

您可以简单地使用exports来打破这个工作版本:

 exports = Person; // wont' work exports.Person = Person; // still won't work (until you resolve it as new Person.Person('Aron') or ..require(..).Person) Which is not readable.. 

为什么我们有出口呢? 有人可以向我解释使用出口,而不是module.exports的好处吗?

感谢提前!

如果您只是将属性添加到module.exportsexports ,则可以修改其中一个并获得相同的结果。 这是因为module.exportsexports最初都指向了完全相同的对象。 所以,如果你修改一个,另一个指向同一个对象,所以这个改变将会在任何一个中看到。 exports显然只是作为一个打字快捷键提供的,所以你不必引用module.exports

所以,这是非常安全的:

 exports.foo = 123; 

要么

 module.exports.foo = 123; 

两者都创build完全相同的结果,并且都是安全的,因为它们都只是将属性分配给同一个对象。

但是,如果您正在创build并分配一个全新的导出对象,那么您必须将该对象分配给module.exports 。 只分配给exports不会对你有好处。

语法:

 exports = module.exports = {foo: 1}; 

绝对确保在这方面没有错误,可能是为什么推荐。

我不明白的是为什么我们需要exports ,因为我们可以完全使用module.exports

只要你的代码从不使用exports ,你可以使用module.exports而不用担心exports 。 你不需要exports 。 这很可能是为了方便而提供的,但正如您已经发现,如果使用不当,便利可能会导致错误。

为什么我们有出口呢? 有人可以向我解释使用出口,而不是module.exports的好处吗?

exports可能只是作为打字便利而提供的。 通过module.exports使用exports的唯一好处是键入less一些,也许是一个小小的性能差异,因为有一个较less的属性查找。 我个人只是假装exports不在那里,我从来没有使用它。 我逻辑上认为module.exports作为出口的真正位置,所以我只是在那里分配或修改,从来没有这样做的问题。


这是更长的解释。

当一个模块被初始化时,它被封装在一个看起来像这样的函数中:

 (function (exports, require, module, __filename, __dirname) { //contents from file1.js module.exports = '123; }); 

这是moduleexports的定义来自哪里。 默认情况下,当这个函数第一次被执行并且你的模块代码开始运行时, module.exports === exports 。 但是, exports在这里只是一个方便。 真正的出口在module.exports中。 所以,如果你只是这样做:

 (function (exports, require, module, __filename, __dirname) { //contents from file1.js exports = {foo: 123}; }); 

这最终没有做任何事情,因为module.exports根本不会受到影响,这就是真正的出口。 但是,如果你这样做:

 (function (exports, require, module, __filename, __dirname) { //contents from file1.js module.exports = {foo: 123}; }); 

然后,真正的出口确实被修改,你的模块将正常工作,但只要你执行module.exports = {foo: 123}; ,你已经使module.exports指向新的对象,它现在将指向与exports点不同的对象。 所以,为了全面的安全,有人build议你这样做:

 (function (exports, require, module, __filename, __dirname) { //contents from file1.js exports = module.exports = {foo: 123}; }); 

然后, exportsmodule.exports总是指向同一个对象。


如果你永远不用自己的exports ,那么你永远不需要分配任何东西,你可以这样做:

 module.exports = {foo: 123}; 

而且,根本没有问题。 但是,如果您更改了module.exports指向的对象,则必须确保没有代码实际上仅使用exports