转载:module.exports 和 exports的区别
1. module.exports
CommonJS
规范规定,每个模块内部,module
变量代表当前模块。这个变量是一个对象,它的exports
属性(即module.exports
)是对外的接口。加载某个模块,其实是加载该模块的module.exports
属性。
function hello() {
console.log('Hello, world!');
}
function world(name) {
console.log('Hello, ' + name);
}
module.exports = {
hello: hello,
world: world
};
上面代码通过module.exports输出函数hello和world。
2. exports
function hello() {
console.log('Hello, world!');
}
function world(name) {
console.log('Hello, ' + name);
}
exports.hello = hello;
exports.world= world;
不可以直接对进行exports赋值:
exports = {
hello: hello,
world: world
};//这样代码不报错, 但是没有用, 接口并未暴露出来. 原因请看下面
3. 原因
首先,Node会把整个待加载的 .js文件放入一个包装函数load中执行。在执行这个load()函数前,Node事先准备好了module对象. module中有一个空的exports方法.
var load = function (exports, module) {
// .js的文件内容
...
// load函数返回:
return module.exports;
};
var exported = load(module.exports, module);
那么为什么在自己的 .js 文件中写成exports = { … }会没有效果呢 ?
系统自动给nodejs 文件增加2个变量 exports 和 module, module 又有一个属性 exports, 这个exports 属性指向一个空对象 {}; 同时 exports这个变量也指向了这个空对象{};
于是就有了 exports => {} <=module.exports.
这2个exports
**其实是没有直接关系的,唯一的关系是: 他们初始都指向同一个空对象{}; **
如果其中一个不指向做个空对象了, 那么他们的关系就没有了. 因此也就没有任何效果了.
4. 总结
因此如果是想要键值对象的这种格式, exports.text = …; 是可以的.
但如果是一个数组或者是函数. 只有module.exports = function(){ }有效.
因此, 不论任何时候都推荐用module.exports