面试题答案
一键面试主要区别
- 本质:
exports
是module.exports
的一个引用。在Node.js模块加载机制中,每个模块内部都有一个module
对象,module.exports
初始是一个空对象{}
,而exports
指向module.exports
。- 当直接给
exports
赋值一个全新的对象(比如exports = {newProp: 'newValue'}
)时,exports
就不再指向module.exports
,这种赋值操作不会影响到module.exports
,模块最终导出的还是module.exports
原来的内容。
- 赋值影响:
- 如果通过给
exports
添加属性的方式(如exports.fun = function() {}
),由于exports
指向module.exports
,实际上是给module.exports
添加属性,最终模块导出的对象就会包含这些属性。 - 而如果直接对
module.exports
进行赋值(如module.exports = {newFun: function() {}}
),会改变module.exports
本身的引用,模块导出的就是这个新赋值的对象。
- 如果通过给
场景举例
- 使用
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));
- 使用
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());