我在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允许在需要时像调用函数一样调用database_module函数。简单地设置导出不允许函数导出,因为node导出对象模块。导出引用。以下代码不允许用户调用函数。
模块.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不导出导出当前引用的对象,而是导出导出最初引用的对象的财产。虽然Node.js确实导出了对象module.exports引用,但允许您像函数一样调用它。
第二个最不重要的原因
他们设置了module.exports和exports,以确保导出不引用先前导出的对象。通过设置这两个选项,您可以使用导出作为速记,并避免以后可能出现的错误。
使用exports.rop=true而不是module.exports.rop=true可以保存字符并避免混淆。
其他回答
JavaScript通过引用的副本传递对象
这与JavaScript中通过引用传递对象的方式有细微差别。
exports和module.exports都指向同一个对象。exports是变量,module.exports是模块对象的属性。
假设我写了这样的东西:
exports = {a:1};
module.exports = {b:12};
exports和module.exports现在指向不同的对象。修改导出不再修改module.exports。
当import函数检查module.exports时,它得到{b:12}
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() { ... }
要了解这些差异,您必须首先了解Node.js在运行时对每个模块做了什么。Node.js为每个模块创建一个包装函数:
(function(exports, require, module, __filename, __dirname) {
})()
注意,第一个param导出是一个空对象,第三个param模块是一个具有许多财产的对象,其中一个财产名为exports。这是导出的来源和module.exports的来源。前者是变量对象,后者是模块对象的属性。
在模块中,Node.js在开始时自动执行以下操作:module.exports=exports,并最终返回module.exports。
因此,您可以看到,如果您为导出重新分配一些值,那么它不会对module.exports产生任何影响
let exports = {};
const module = {};
module.exports = exports;
exports = { a: 1 }
console.log(module.exports) // {}
但是如果你更新导出的财产,它肯定会对module.exports产生影响。因为它们都指向同一个对象。
let exports = {};
const module = {};
module.exports = exports;
exports.a = 1;
module.exports.b = 2;
console.log(module.exports) // { a: 1, b: 2 }
还要注意,如果您将另一个值重新分配给module.exports,那么对于导出更新来说似乎没有意义。由于module.exports指向另一个对象,因此忽略导出上的每个更新。
let exports = {};
const module = {};
module.exports = exports;
exports.a = 1;
module.exports = {
hello: () => console.log('hello')
}
console.log(module.exports) // { hello: () => console.log('hello')}
我只是做了一些测试,结果发现,在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)
exports:它是对module.exports对象的引用exports和module.exports都指向同一个对象直到我们更改导出对象的引用
例子:
如果exports.a=10,则module.exports.a=10如果我们在代码中显式地重新分配exports对象exports={}现在失去了对module.exports的引用