Nodejs exports和module.exports:为什么我们还需要出口呢?

时间:2016-03-06 11:28:21

标签: node.js

在我阅读another question on this topic:

上的一些答案时

我(猜)了解export和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..

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

谢谢你!

1 个答案:

答案 0 :(得分:6)

如果您只是向module.exportsexports添加属性,则可以修改其中任何一个并获得相同的结果。这是因为module.exportsexports最初都指向完全相同的对象。因此,如果您修改一个,则另一个指向同一个对象,以便在任何一个中看到更改。 exports显然只是作为输入快捷方式提供,因此您无需参考module.exports

所以,这是非常安全的:

exports.foo = 123;

或者

module.exports.foo = 123;

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

但是,如果要创建并分配一个全新的导出对象,那么必须将该对象分配给module.exports。仅将其分配给exports对您没有任何好处。

语法:

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

绝对确保在这方面没有错误,这可能是推荐的原因。

  

我不明白的是,为什么我们无论如何都需要exports   只使用module.exports完美地解决问题。

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

  

为什么我们还有出口?有人可以向我解释这些好处   使用导出而不是module.exports?

exports可能只是提供打字方便。使用exports而非module.exports的唯一好处是输入少一点,可能性能差异很小,因为只有少量的属性查找。我个人假装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不同的对象指向。因此,为了完全安全,有些人建议你这样做:

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

然后,exportsmodule.exports始终指向同一个对象。

如果您从不单独使用exports,那么您根本不需要为其分配任何内容,您可以这样做:

module.exports = {foo: 123};

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