蕾妮的答案解释得很好。用一个例子补充回答:
Node对你的文件做了很多事情,其中一个重要的是包装你的文件。在nodejs源代码"模块。Exports返回。让我们回过头来了解一下包装器。假设你有
greet.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。
此时模块。导出和导出指向同一个引用。
现在,想象你重写
greet.js作为
exports = function () {
console.log('Hello World');
};
console.log(exports);
console.log(module.exports);
输出将是
[Function]
{}
原因是:模块。Exports是一个空对象。我们没有将任何东西设置为模块。我们设置Exports = function().....在new greet.js中。因此,模块。出口是空的。
技术上导出和模块。出口应该指向相同的参考(这是正确的!!)但是我们在赋值function()....时使用“=”到导出,这将在内存中创建另一个对象。因此,模块。输出和输出产生不同的结果。当涉及到输出时,我们无法覆盖它。
现在,想象你重写(这叫做突变)
greet.js(指Renee answer)为
exports.a = function() {
console.log("Hello");
}
console.log(exports);
console.log(module.exports);
输出将是
{ a: [Function] }
{ a: [Function] }
正如你所看到的模块。Exports和Exports指向同一个引用,这是一个函数。如果你在导出上设置了一个属性,那么它将在模块上设置。因为在JS中,对象是通过引用传递的。
结论是始终使用模块。导出以避免混淆。
希望这能有所帮助。快乐编码:)