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

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

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


当前回答

这是曼宁出版的动作书中关于node.js中节点模块的一个很好的描述。最终在应用程序中导出的是module.exports.exportsup简单地作为module.exports的全局引用,它最初定义为可以向其中添加财产的空对象。所以exports.myFunc只是一种速记对于module.exports.myFunc。因此,如果将导出设置为其他值,则会断开引用模块导出和导出。因为module.exports是真正的导出,导出将不再按预期工作,它不引用模块.不再导出。如果要维护该链接,可以创建module.exports再次引用导出如下:

module.exports = exports = db;

其他回答

在节点js中,module.js文件用于运行module.load系统。每当节点执行文件时,它都会将js文件内容包装如下

'(function (exports, require, module, __filename, __dirname) {',+
     //your js file content
 '\n});'

由于这种包装在urjs源代码中,您可以访问导出、require、模块等。。之所以使用这种方法,是因为没有其他方法可以将js文件中的功能写入另一个文件。

然后节点使用c++执行这个包装函数。此时,传递到此函数的exports对象将被填充。

您可以在这个函数中看到参数导出和模块。实际上,exports是模块构造函数函数的公共成员。

查看以下代码

将此代码复制到b.js中

console.log("module is "+Object.prototype.toString.call(module));
console.log("object.keys "+Object.keys(module));
console.log(module.exports);
console.log(exports === module.exports);
console.log("exports is "+Object.prototype.toString.call(exports));
console.log('----------------------------------------------');
var foo = require('a.js');
console.log("object.keys of foo: "+Object.keys(foo));
console.log('name is '+ foo);
foo();

将此代码复制到.js

exports.name = 'hello';
module.exports.name = 'hi';
module.exports.age = 23;
module.exports = function(){console.log('function to module exports')};
//exports = function(){console.log('function to export');}

现在使用节点运行

这是输出

module is [object Object]
object.keys id,exports,parent,filename,loaded,children,paths
{}
true

导出为[对象对象]

foo的object.keys:名称是函数(){console.log('模块导出函数')}功能到模块导出

现在删除.js中的注释行,并注释该行上方的行然后删除b.js的最后一行并运行。

在javascript世界中,不能重新分配作为参数传递的对象,但当该函数的对象设置为另一个函数的参数时,可以更改该函数的公共成员

请记住

仅当您想在使用require关键字时获取函数时,才使用module.exports。在上面的例子中,我们varfoo=require(a.js);你可以看到我们可以将foo作为函数调用;

节点文档就是这样解释的导出对象是由Module系统创建的。有时这是不可接受的,许多人希望自己的模块是某个类的实例。为此,请将所需的导出对象分配给Module.exports

“如果您希望模块导出的根是一个函数(例如构造函数),或者如果您希望在一个赋值中导出一个完整的对象,而不是一次生成一个属性,请将其分配给module.exports而不是导出。”-http://nodejs.org/api/modules.html

1.导出->用作单例实用程序2.模块导出->用作逻辑对象,如服务、模型等

这是曼宁出版的动作书中关于node.js中节点模块的一个很好的描述。最终在应用程序中导出的是module.exports.exportsup简单地作为module.exports的全局引用,它最初定义为可以向其中添加财产的空对象。所以exports.myFunc只是一种速记对于module.exports.myFunc。因此,如果将导出设置为其他值,则会断开引用模块导出和导出。因为module.exports是真正的导出,导出将不再按预期工作,它不引用模块.不再导出。如果要维护该链接,可以创建module.exports再次引用导出如下:

module.exports = exports = db;

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

例子:

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