我在Node.js模块中找到了以下契约:

module.exports = exports = nano = function database_module(cfg) {...}

我想知道module.exports和exports之间有什么区别,为什么在这里使用它们。


当前回答

我只是做了一些测试,结果发现,在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)

其他回答

让我们用两种方式创建一个模块:

单向

var aa = {
    a: () => {return 'a'},
    b: () => {return 'b'}
}

module.exports = aa;

第二种方式

exports.a = () => {return 'a';}
exports.b = () => {return 'b';}

这就是require()集成模块的方式。

第一种方式:

function require(){
    module.exports = {};
    var exports = module.exports;

    var aa = {
        a: () => {return 'a'},
        b: () => {return 'b'}
    }
    module.exports = aa;

    return module.exports;
}

第二种方式

function require(){
    module.exports = {};
    var exports = module.exports;

    exports.a = () => {return 'a';}
    exports.b = () => {return 'b';}

    return 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() { ... }

设置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}

var a = {},md={};

//首先,exports和module.exports指向同一个空Object

exp = a;//exports =a;
md.exp = a;//module.exports = a;

exp.attr = "change";

console.log(md.exp);//{attr:"change"}

//如果将exp指向其他对象,而不是将其属性指向其他对象。md.exp将为空对象{}

var a ={},md={};
exp =a;
md.exp =a;

exp = function(){ console.log('Do nothing...'); };

console.log(md.exp); //{}