MST

星途 面试题库

面试题:Node.js 模块解耦中exports与module.exports的区别

在Node.js使用模块实现功能解耦时,exports与module.exports都用于导出模块内容,请阐述它们的主要区别,并且举例说明在何种场景下会使用到这两种不同的导出方式。
15.0万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

主要区别

  1. 本质
    • exportsmodule.exports的一个引用。在Node.js模块加载机制中,每个模块内部都有一个module对象,module.exports初始是一个空对象{} ,而exports指向module.exports
    • 当直接给exports赋值一个全新的对象(比如exports = {newProp: 'newValue'})时,exports就不再指向module.exports,这种赋值操作不会影响到module.exports,模块最终导出的还是module.exports原来的内容。
  2. 赋值影响
    • 如果通过给exports添加属性的方式(如exports.fun = function() {}),由于exports指向module.exports,实际上是给module.exports添加属性,最终模块导出的对象就会包含这些属性。
    • 而如果直接对module.exports进行赋值(如module.exports = {newFun: function() {}}),会改变module.exports本身的引用,模块导出的就是这个新赋值的对象。

场景举例

  1. 使用exports的场景: 当你只是想简单地给模块添加一些属性或方法,而不改变模块导出对象的引用时,使用exports比较方便。例如,创建一个简单的工具模块:
// utils.js
exports.add = function(a, b) {
    return a + b;
};
exports.subtract = function(a, b) {
    return a - b;
};

在其他模块中使用:

const utils = require('./utils');
console.log(utils.add(2, 3)); 
console.log(utils.subtract(5, 3)); 
  1. 使用module.exports的场景: 当你希望模块导出一个特定的复杂对象、函数或者类时,直接对module.exports赋值。比如导出一个类:
// Person.js
function Person(name) {
    this.name = name;
}
Person.prototype.sayHello = function() {
    console.log('Hello, I\'m'+ this.name);
};
module.exports = Person;

在其他模块中使用:

const Person = require('./Person');
const john = new Person('John');
john.sayHello(); 

或者导出一个复杂对象:

// data.js
const data = {
    users: [
        {name: 'Alice', age: 25},
        {name: 'Bob', age: 30}
    ],
    getUsers: function() {
        return this.users;
    }
};
module.exports = data;

在其他模块中使用:

const data = require('./data');
console.log(data.getUsers());