区别
- 本质:
exports
是module.exports
的一个引用。在Node.js模块中,每个模块内部都有一个module
对象,这个对象有一个exports
属性,exports
其实就是module.exports
的别名。
- 当你使用
exports.xxx = value
时,实际上是在修改module.exports
对象的属性。
- 赋值操作差异:
- 如果直接对
exports
进行赋值操作,例如exports = { newProp: 'newValue' }
,这会切断exports
与module.exports
的引用关系。之后通过require
引入该模块时,并不会得到新赋值的对象,而是原来module.exports
对象(在赋值前的状态)。
- 而对
module.exports
进行赋值操作,例如module.exports = { newProp: 'newValue' }
,这样是有效的,通过require
引入该模块时,会得到新赋值的对象。
场景选择
- 使用exports的场景:
- 当你只是想向模块外部暴露一些属性或方法时,使用
exports
比较方便。例如:
// mathUtils.js
exports.add = function(a, b) {
return a + b;
};
exports.subtract = function(a, b) {
return a - b;
};
- 在这种场景下,只是简单地在
module.exports
对象上添加属性(函数也是对象的属性),使用exports
可以保持代码简洁,因为不需要每次都写module.exports
。
- 使用module.exports的场景:
- 当你想完全替换默认的
module.exports
对象,返回一个全新的对象、函数、数组等类型时,就需要使用module.exports
。例如:
// person.js
function Person(name, age) {
this.name = name;
this.age = age;
}
module.exports = Person;
- 这里将整个
Person
构造函数赋值给module.exports
,如果使用exports = Person
是无效的,必须使用module.exports
才能正确导出,使得其他模块可以通过require
引入并使用Person
构造函数创建实例。又如,导出一个复杂的对象结构:
// config.js
const config = {
database: {
host: 'localhost',
port: 3306,
user: 'root',
password: '123456'
},
server: {
port: 8080
}
};
module.exports = config;
- 这种情况下,直接对
module.exports
赋值,方便导出一个完整的复杂对象。