我在Node.js模块中找到了以下契约:
module.exports = exports = nano = function database_module(cfg) {...}
我想知道module.exports和exports之间有什么区别,为什么在这里使用它们。
我在Node.js模块中找到了以下契约:
module.exports = exports = nano = function database_module(cfg) {...}
我想知道module.exports和exports之间有什么区别,为什么在这里使用它们。
当前回答
module.exports和exports都指向同一个函数database_module(cfg){…}。1|变量a,b;2|a=b=function(){console.log(“旧”);};3|b=函数(){console.log(“New”);};4|5|a();//“旧”6|b();//“新建”您可以将第3行的b更改为a,输出是相反的。结论是:a和b是独立的。因此module.exports=exports=nano=function database_module(cfg){…}相当于:var f=函数database_module(cfg){…};模块导出=f;出口=f;假设上面是foo.js所需要的module.js。module.exports=exports=nano=function database_module(cfg){…}的好处现在很清楚了:在foo.js中,由于module.exports是必需的('./module.js'):var output=require('./modules.js')();在moduls.js中:可以使用exports代替module.exports。
因此,如果exports和module.exports都指向同一个对象,您会很高兴。
其他回答
1.导出->用作单例实用程序2.模块导出->用作逻辑对象,如服务、模型等
最初,module.exports=导出,require函数返回module.exports引用的对象。
如果我们向对象添加属性,比如exports.a=1,那么module.exports和exports仍然引用同一个对象。因此,如果我们调用require并将模块分配给变量,那么该变量具有属性a,其值为1;
但是如果我们重写其中一个,例如exports=function(){},那么它们现在就不同了:exports引用新对象,module.exports引用原始对象。如果我们需要该文件,它将不会返回新对象,因为module.exports不引用新对象。
对我来说,我将继续添加新属性,或者将它们都覆盖到新对象中。只是忽略一个是不正确的。请记住,module.exports才是真正的老板。
exports和module.exports是相同的,除非在模块内重新分配导出。
考虑这一点最简单的方法是认为这一行隐式地位于每个模块的顶部。
var exports = module.exports = {};
如果在模块内重新分配导出,则在模块内将其重新分配,并且不再等于module.exports。这就是为什么,如果要导出函数,必须执行以下操作:
module.exports = function() { ... }
如果只将函数(){…}分配给导出,则将导出重新分配为不再指向module.exports。
如果您不想每次通过module.exports引用函数,可以执行以下操作:
module.exports = exports = function() { ... }
注意,module.exports是最左边的参数。
将财产附加到导出不一样,因为您不需要重新分配它。这就是为什么可以这样做的原因
exports.foo = function() { ... }
我只是做了一些测试,结果发现,在nodejs的模块代码中,应该是这样的:
var module.exports = {};
var exports = module.exports;
so:
1:
exports = function(){}; // this will not work! as it make the exports to some other pointer
module.exports = function(){}; // it works! cause finally nodejs make the module.exports to export.
2:
exports.abc = function(){}; // works!
exports.efg = function(){}; // works!
3:但是,在这种情况下
module.exports = function(){}; // from now on we have to using module.exports to attach more stuff to exports.
module.exports.a = 'value a'; // works
exports.b = 'value b'; // the b will nerver be seen cause of the first line of code we have do it before (or later)
这显示了require()如何以最简单的形式工作,摘自Eloquent JavaScript
问题模块不可能直接导出导出对象以外的值,例如函数。例如,模块可能只希望导出其定义的对象类型的构造函数。现在,它无法做到这一点,因为require始终使用它创建的导出对象作为导出值。
解决方案为模块提供另一个变量module,它是一个具有属性导出的对象。此属性最初指向require创建的空对象,但可以用另一个值覆盖以导出其他对象。
function require(name) {
if (name in require.cache)
return require.cache[name];
var code = new Function("exports, module", readFile(name));
var exports = {}, module = {exports: exports};
code(exports, module);
require.cache[name] = module.exports;
return module.exports;
}
require.cache = Object.create(null);