Node.js 中 exports 与 module.exports 的区别详解
本文深入解析Node.js中exports与module.exports的关系。明确module.exports才是模块的真实接口,exports仅是其引用。通过代码示例说明当module.exports被重新赋值时,exports属性将被忽略,模块返回新定义的值。掌握这一机制有助于避免模块导出错误,灵活使用对象、函数或数组等任意JavaScript类型作为模块出口。
Node.js模块基础与exports用法
在Node.js开发中,你应当对模块系统中的exports对象非常熟悉,它是构建和导出模块接口的常用方式。以rocker.js文件为例进行说明。
示例代码如下:
exports.name = function() {
console.log('My name is Lemmy Kilmister');
}; 在其他文件中,可以通过以下方式引用该模块:
示例代码如下:
var rocker = require('./rocker.js');
rocker.name(); // 输出 'My name is Lemmy Kilmister' 那到底Module.exports是什么呢?它是否合法呢?
module.exports与exports的核心关系
实际上,module.exports才是模块真正的接口,而exports仅仅是一个辅助工具。Node.js最终返回给调用者的内容是module.exports,而非exports。
通常情况下,exports收集到的所有属性和方法都会被赋值给module.exports。但这一行为有一个前提条件:module.exports本身必须是一个空对象,即不具备任何预先定义的属性和方法。如果module.exports已经被赋予了特定的值或方法,那么通过exports添加的属性将被忽略。
module.exports覆盖机制与类型示例
修改rocker.js文件内容如下:
示例代码如下:
module.exports = 'ROCK IT!';
exports.name = function() {
console.log('My name is Lemmy Kilmister');
}; 再次引用并执行rocker.js模块:
示例代码如下:
var rocker = require('./rocker.js');
rocker.name(); // 报错:TypeError: Object ROCK IT! has no method 'name' 此时出现错误提示:对象“ROCK IT!”没有name方法。
在上述例子中,rocker模块忽略了通过exports收集的name方法,直接返回了字符串“ROCK IT!”。这证明了模块并不一定非要返回一个实例化对象。模块的返回值可以是任何合法的JavaScript数据类型,包括布尔值、数字、日期、JSON对象、字符串、函数或数组等。
模块的具体类型完全取决于你赋予module.exports的值。如果你没有显式地为module.exports设置任何属性或方法,那么模块将返回通过exports附加到module.exports上的属性集合。
以下示例展示如何将模块定义为一个类:
示例代码如下:
module.exports = function(name, age) {
this.name = name;
this.age = age;
this.about = function() {
console.log(this.name +' is '+ this.age +' years old');
};
}; 应用该模块的方式如下:
示例代码如下:
var Rocker = require('./rocker.js');
var r = new Rocker('Ozzy', 62);
r.about(); // 输出 Ozzy is 62 years old 另一个示例展示如何将模块定义为一个数组:
示例代码如下:
module.exports = ['Lemmy Kilmister', 'Ozzy Osbourne', 'Ronnie James Dio', 'Steven Tyler', 'Mick Jagger']; 应用该模块的方式如下:
示例代码如下:
var rocker = require('./rocker.js');
console.log('Rockin in heaven: ' + rocker[2]); // 输出 Rockin in heaven: Ronnie James Dio 现在可以明确:如果你希望模块导出特定类型的值(如字符串、数组或构造函数),应使用module.exports;如果你希望导出一个典型的实例化对象,则使用exports更为方便。
两种导出方式的对比与最佳实践
向module.exports添加属性与向exports添加属性在语法上类似。例如:
示例代码如下:
module.exports.name = function() {
console.log('My name is Lemmy Kilmister');
}; 同样,使用exports也可以实现类似效果:
示例代码如下:
exports.name = function() {
console.log('My name is Lemmy Kilmister');
}; 需要注意的是,这两种写法的结果并不完全相同。如前所述,module.exports是真正的接口,exports只是其辅助工具。通常推荐使用exports进行导出,除非你需要将模块从默认的“实例化对象”更改为其他特定类型。
Node.js中使用path模块获取文件名
2026-11-05 15:15:15
Node.js中url模块与querystring模块处理查询字符串的区别
2026-11-05 15:04:45
JavaScript(JS)主要用来做什么
2026-11-05 10:10:47
怎么修改Node.js和npm的全局安装路径与缓存目录
2026-11-04 19:48:28
NW.js 常见问题排查:Node 模块加载失败与版本兼容解决
2026-11-04 11:22:45
