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

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

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


当前回答

exports:它是对module.exports对象的引用exports和module.exports都指向同一个对象直到我们更改导出对象的引用

例子:

如果exports.a=10,则module.exports.a=10如果我们在代码中显式地重新分配exports对象exports={}现在失去了对module.exports的引用

其他回答

我发现这个链接对回答上述问题很有用。

http://timnew.me/blog/2012/04/20/exports-vs-module-exports-in-node-js/

添加到其他帖子节点中的模块系统

var exports = module.exports 

在执行代码之前。因此,当您想要exports=foo时,您可能需要执行module.exports=exports=foo,但使用exports.foo=foo应该可以

基本上,答案在于当通过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 = [];
}

正如您所看到的,每个模块对象都有一个带有名称导出的属性。这是最终作为需求的一部分返回的内容。

require的下一步是将file1.js的内容包装成一个匿名函数,如下所示:

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

这个匿名函数的调用方式如下,这里的模块引用前面创建的模块对象。

(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 = {};

因此,向上面的导出对象添加任何内容都不会对module.exports对象产生任何影响,也不会作为require的一部分导出或返回任何内容。

从文档中

exports变量在模块的文件级范围内可用,并在评估模块之前为其赋值module.exports。它允许快捷方式,因此module.exports.f=。。。可以更简洁地写成exports。f=。。。。但是,请注意,与任何变量一样,如果为导出分配了新值,则不再将其绑定到module.exports:

它只是一个指向module.exports的变量。

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}

以下是

console.log("module:");
console.log(module);

console.log("exports:");
console.log(exports);

console.log("module.exports:");
console.log(module.exports);

也:

if(module.exports === exports){
    console.log("YES");
}else{
    console.log("NO");
}

//YES

注:CommonJS规范只允许使用exports变量来公开公共成员。因此,命名的导出模式是唯一真正与CommonJS规范兼容的模式。module.exports的使用是Node.js提供的扩展,以支持更广泛的模块定义模式。