module.exports vs Node.js中的导出
我在Node.js模块中找到了以下合约:
module.exports = exports = nano = function database_module(cfg) {...}
我想知道module.exports
和exports
之间有什么不同,以及为什么两者都用在这里。
设置module.exports
允许database_module
时要调用的函数的功能等required
。 简单地设置exports
将不允许导出函数,因为节点导出对象module.exports
引用。 以下代码不允许用户调用该函数。
module.js
以下将无法使用。
exports = nano = function database_module(cfg) {return;}
如果设置了module.exports
,以下将会工作。
module.exports = exports = nano = function database_module(cfg) {return;}
安慰
var func = require('./module.js');
// the following line will **work** with module.exports
func();
基本上, node.js不会导出exports
当前引用的对象,但会exports
最初引用的导出属性。 尽管Node.js不会导出对象module.exports
引用,但可以将其称为函数。
第二个不重要的原因
他们设置module.exports
和exports
以确保exports
不引用先前导出的对象。 通过设置您的exports
作为速记,并避免后来的潜在错误。
使用module.exports.prop = true
exports.prop = true
而不是module.exports.prop = true
可以保存字符并避免混淆。
即使问题早已得到回答和接受,我只想分享我的2分钱:
你可以想象,在你的文件的开头有一些像(仅仅为了解释):
var module = new Module(...);
var exports = module.exports;
因此,无论您只是牢记module.exports
和NOT exports
将从您的模块返回,当您从其他地方需要该模块时。
所以当你做这样的事情时:
exports.a = function() {
console.log("a");
}
exports.b = function() {
console.log("b");
}
要添加2函数“a”和“B”在其上太module.exports点对象,所以typeof
返回的结果将是一个object
: { a: [Function], b: [Function] }
当然,如果您在本例中使用module.exports
而不是exports
则会得到相同的结果。
在这种情况下,您希望module.exports的行为类似于导出值的容器。 然而,如果你只想导出一个构造函数,那么你应该知道使用module.exports
或exports
;(再次记住,当你需要某些东西而不是导出时,module.exports会被返回)。
module.exports = function Something() {
console.log('bla bla');
}
现在typeof返回结果是'function'
,你可以要求它并立即调用,如:
var x = require('./file1.js')();
因为你覆盖返回的结果是一个函数。
但是,使用exports
你不能使用像这样的东西:
exports = function Something() {
console.log('bla bla');
}
var x = require('./file1.js')(); //Error: require is not a function
因为对于exports
,引用不再'指向' module.exports
指向的对象,所以exports
和module.exports
之间不再有关系。 在这种情况下,module.exports仍然指向将返回的空对象{}
。
来自另一主题的接受答案也应该有所帮助:Javascript是否通过引用?
基本上,答案在于通过require
语句require
模块时发生的真实情况。 假设这是第一次需要该模块。
例如:
var x = require('file1.js');
file1.js的内容:
module.exports = '123';
当执行上述语句时,将创建一个Module
对象。 它的构造函数是:
function Module(id, parent) {
this.id = id;
this.exports = {};
this.parent = parent;
if (parent && parent.children) {
parent.children.push(this);
}
this.filename = null;
this.loaded = false;
this.children = [];
}
正如你看到的每个模块对象都有一个名称为exports
的属性。 这是最终返回作为require
一部分。
require的下一步是将file1.js的内容封装到如下的匿名函数中:
(function (exports, require, module, __filename, __dirname) {
//contents from file1.js
module.exports = '123;
});
而这个匿名函数被调用下面的方式, module
这里指的是Module
前面创建的对象。
(function (exports, require, module, __filename, __dirname) {
//contents from file1.js
module.exports = '123;
}) (module.exports,require, module, "path_to_file1.js","directory of the file1.js");
正如我们在函数内部看到的, exports
正式参数指的是module.exports
。 实质上,它是为模块程序员提供的便利。
然而,这种便利需要谨慎行事。 无论如何,如果试图将新对象分配给出口,确保我们这样做。
exports = module.exports = {};
如果我们按照错误的方式执行它, module.exports
仍然会指向作为模块实例的一部分创建的对象。
exports = {};
因此,向上述exports对象添加任何内容都不会对module.exports对象产生任何影响,并且不会将任何内容作为require的一部分导出或返回。
链接地址: http://www.djcxy.com/p/17371.html