蕾妮的回答得到了很好的解释。除了一个例子的答案:
Node 对你的文件做了很多事情,其中一项重要的事情就是包装你的文件。返回内部 nodejs 源代码“module.exports”。让我们退后一步,了解包装器。假设你有
问候.js
var greet = function () {
console.log('Hello World');
};
module.exports = greet;
上面的代码在 nodejs 源代码中被包装为 IIFE(立即调用函数表达式),如下所示:
(function (exports, require, module, __filename, __dirname) { //add by node
var greet = function () {
console.log('Hello World');
};
module.exports = greet;
}).apply(); //add by node
return module.exports; //add by node
并且上面的函数被调用(.apply())并返回module.exports。这时module.exports和exports指向同一个引用。
现在,想象一下你将 greet.js 重写为
exports = function () {
console.log('Hello World');
};
console.log(exports);
console.log(module.exports);
输出将是
[Function]
{}
原因是:module.exports 是一个空对象。我们没有为 module.exports 设置任何东西,而是在新的greet.js 中设置了exports = function(.....。所以,module.exports 是空的。
从技术上讲,导出和 module.exports 应该指向相同的引用(这是正确的!!)。但是我们在将 function().... 分配给导出时使用“=”,这会在内存中创建另一个对象。因此,module.exports 和exports 产生不同的结果。当涉及到导出时,我们无法覆盖它。
现在,假设你重写(这称为 Mutation)greet.js(指 Renee 的回答)为
exports.a = function() {
console.log("Hello");
}
console.log(exports);
console.log(module.exports);
输出将是
{ a: [Function] }
{ a: [Function] }
如您所见,module.exports 和exports 指向相同的引用,这是一个函数。如果您在导出上设置属性,那么它将在 module.exports 上设置,因为在 JS 中,对象是通过引用传递的。
结论是始终使用 module.exports 以避免混淆。希望这可以帮助。快乐编码:)