我在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之间有什么区别,为什么在这里使用它们。
当前回答
在节点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
其他回答
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); //{}
最初,module.exports=导出,require函数返回module.exports引用的对象。
如果我们向对象添加属性,比如exports.a=1,那么module.exports和exports仍然引用同一个对象。因此,如果我们调用require并将模块分配给变量,那么该变量具有属性a,其值为1;
但是如果我们重写其中一个,例如exports=function(){},那么它们现在就不同了:exports引用新对象,module.exports引用原始对象。如果我们需要该文件,它将不会返回新对象,因为module.exports不引用新对象。
对我来说,我将继续添加新属性,或者将它们都覆盖到新对象中。只是忽略一个是不正确的。请记住,module.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都指向同一个对象,您会很高兴。
在节点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
让我们用两种方式创建一个模块:
单向
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;
}