MST
星途 面试题库

面试题:Node.js模块系统中exports和module.exports的区别

在Node.js模块系统里,exports和module.exports都用于导出模块内容,请详细阐述它们之间的区别,并且举例说明在哪些场景下会选择使用exports,哪些场景下会选择使用module.exports。
13.0万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

区别

  1. 本质
    • exportsmodule.exports的一个引用。在Node.js模块中,每个模块内部都有一个module对象,这个对象有一个exports属性,exports其实就是module.exports的别名。
    • 当你使用exports.xxx = value时,实际上是在修改module.exports对象的属性。
  2. 赋值操作差异
    • 如果直接对exports进行赋值操作,例如exports = { newProp: 'newValue' },这会切断exportsmodule.exports的引用关系。之后通过require引入该模块时,并不会得到新赋值的对象,而是原来module.exports对象(在赋值前的状态)。
    • 而对module.exports进行赋值操作,例如module.exports = { newProp: 'newValue' },这样是有效的,通过require引入该模块时,会得到新赋值的对象。

场景选择

  1. 使用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
  1. 使用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赋值,方便导出一个完整的复杂对象。