MST
星途 面试题库

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

在Node.js模块化开发中,exports与module.exports都用于导出模块内容,请详细阐述它们之间的区别,并举例说明在何种场景下可能会因为对这种区别理解不当而导致代码出错。
24.3万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

区别

  1. 本质
    • exports实际上是module.exports的一个引用。在Node.js模块的顶层作用域中,Node.js会自动创建一个module对象,这个对象有一个exports属性,exports就是指向module.exports
    • module.exports才是真正决定模块对外暴露内容的对象。
  2. 赋值操作
    • exports进行重新赋值,并不会改变module.exports的指向。例如:
exports = {
    data: 'new value'
};
// 这里的exports重新赋值,不会影响module.exports,外部引用模块时获取不到这个新对象
  • module.exports进行赋值,会直接改变模块对外暴露的内容。例如:
module.exports = {
    data: 'new value'
};
// 外部引用模块时,获取到的就是这个新对象
  1. 添加属性操作
    • exports添加属性,实际上是向module.exports添加属性。例如:
exports.data = 'value';
// 等同于module.exports.data = 'value';
  • module.exports添加属性,直接影响模块对外暴露的内容。例如:
module.exports.data = 'value';

因理解不当导致代码出错的场景

假设我们有一个模块math.js,代码如下:

// math.js
exports.add = function(a, b) {
    return a + b;
};
exports = {
    subtract: function(a, b) {
        return a - b;
    }
};

然后在另一个文件main.js中引用这个模块:

// main.js
const math = require('./math');
console.log(math.add(2, 3)); // 这里会出错,因为exports重新赋值后,add函数不再属于导出内容

在上述场景中,开发者本意可能是想添加一个subtract函数并导出,但因为对exportsmodule.exports的区别理解不当,重新赋值exports导致之前添加的add函数不再属于模块的导出内容,从而在使用时出错。如果要正确导出两个函数,应该使用module.exports或者直接在exports上添加属性,如下:

// 正确方式一:使用module.exports
module.exports = {
    add: function(a, b) {
        return a + b;
    },
    subtract: function(a, b) {
        return a - b;
    }
};
// 正确方式二:使用exports添加属性
exports.add = function(a, b) {
    return a + b;
};
exports.subtract = function(a, b) {
    return a - b;
};