当我们编写 Node.js 代码时,经常会遇到 exports 和 module.exports,它们都是用来导出模块的。但它们之间有什么区别呢?
1. exports 和 module.exports 区别
在 Node.js 中,每个模块都有一个 module 对象。在 module 对象中,有一个 exports 对象,而且 exports 对象也是 module.exports 对象的一个引用。因此,对于一般情况,我们可以使用 exports 和 module.exports 两者来导出模块。
不过,需要注意的是,exports 只能使用点语法来添加属性或方法,而不能直接覆盖它的引用,因为这样会失去它与 module.exports 的联系。而对于 module.exports,它可以直接赋值为一个新对象,或者一个函数,直接覆盖掉原来的值。
让我们通过两个示例来更加详细地了解这种区别。
2. 示例一
假设我们有一个 hello.js 文件,代码如下:
exports = {
sayHello: function() {
console.log('Hello!');
},
sayHi: function() {
console.log('Hi!');
}
};
我们在另一个文件中导入该模块并调用:
const hello = require('./hello');
hello.sayHello();
这时我们会发现在控制台输出了一个错误信息:
TypeError: hello.sayHello is not a function
这是因为我们使用了 exports 来导出模块,但是在导入 hello 模块的时候,我们使用了 module.exports。
解决方法有两种:
- 修改导入模块的代码,使用 exports:
const { sayHello } = require('./hello');
sayHello();
- 把 exports 的引用指向 module.exports:
module.exports = {
sayHello: function() {
console.log('Hello!');
},
sayHi: function() {
console.log('Hi!');
}
};
// 或者这样写
// exports = module.exports;
3. 示例二
让我们再来看一个例子。
假设我们有一个 utils.js 文件,代码如下:
exports = {
add: function(a, b) {
return a + b;
},
sub: function(a, b) {
return a - b;
}
};
我们在另一个文件中导入该模块并调用:
const utils = require('./utils');
const sum = utils.add(1, 2);
console.log(sum);
这时我们发现什么也没有输出,这是因为我们使用了 exports 来导出模块,但是它无法覆盖掉原先的 module.exports 值,因此最终导出的是空对象 {}。
解决方法有两种:
- 把 add 和 sub 方法添加到 module.exports 中:
module.exports.add = function(a, b) {
return a + b;
};
module.exports.sub = function(a, b) {
return a - b;
};
- 直接覆盖掉 module.exports:
module.exports = {
add: function(a, b) {
return a + b;
},
sub: function(a, b) {
return a - b;
}
};
4. 总结
虽然 exports 和 module.exports 都能用于导出模块,但是它们之间的区别是:
- exports 是 module.exports 的一个引用,不能直接赋值覆盖。
- module.exports 可以直接赋值为一个新对象或一个函数,用于覆盖原来的值。
这是 Node.js 中非常重要的一点,需要注意。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Node.js中exports和module.exports的区别 - Python技术站