在此页面上(http://docs.nodejitsu.com/articles/getting-started/what-is-require),它声明"If you want to set the exports object to a function or a new object, you have to use the module.exports object."
我的问题是为什么 .
// right
module.exports = function () {
console.log("hello world")
}
// wrong
exports = function () {
console.log("hello world")
}
我控制台 . 记录结果( result=require(example.js)
),第一个是 [Function]
,第二个是 {}
.
你能解释一下背后的原因吗?我在这里阅读帖子:module.exports vs exports in Node.js . 它很有用,但没有解释为什么以这种方式设计它的原因 . 如果直接退回出口参考会有问题吗?
4 回答
module
是一个具有exports
属性的纯JavaScript对象 .exports
是一个普通的JavaScript变量,恰好设置为module.exports
. 在文件的末尾,node.js基本上会'return'module.exports
到require
函数 . 在Node中查看JS文件的简化方法可能是:如果你在
exports
上设置了一个属性,就像exports.a = 9;
那样,也会设置module.exports.a
,因为对象在JavaScript中作为引用传递,这意味着如果你将多个变量设置为同一个对象,它们都是同一个对象;那么exports
和module.exports
是同一个对象 .但是如果将
exports
设置为新的,它将不再设置为module.exports
,因此exports
和module.exports
不再是同一个对象 .蕾妮的回答得到了很好的解释 . 除了一个例子的答案:
Node为您的文件做了很多事情,其中一个重要的是WRAPPING您的文件 . 在nodejs内部返回源代码“module.exports” . 让我们退后一步,了解包装器 . 假设你有
greet.js
上面的代码在nodejs源代码中包装为IIFE(Immediately Invoked Function Expression),如下所示:
并调用上述函数(.apply())并返回module.exports . 此时module.exports和exports指向同一个引用 .
现在,假设您重写greet.js为
输出将是
原因是:module.exports是一个空对象 . 我们没有为module.exports设置任何东西,而是在新的greet.js中设置exports = function()..... . 所以,module.exports是空的 .
从技术上讲,exports和module.exports应指向相同的引用(这是正确的!!) . 但是在将function()....赋值给exports时会使用“=”,这会在内存中创建另一个对象 . 因此,module.exports和exports会产生不同的结果 . 谈到出口,我们无法覆盖它 .
现在,想象一下你重写(这叫做Mutation)greet.js(指Renee的回答)as
输出将是
正如您所看到的,module.exports和exports指向同一个引用,这是一个函数 . 如果在exports上设置属性,那么它将在module.exports上设置,因为在JS中,对象是通过引用传递的 .
结论总是使用module.exports来避免混淆 . 希望这可以帮助 . 快乐编码:)
此外,有一件事可能有助于理解:
math.js
client.js
很棒,在这种情况下:
因此,默认情况下,“this”实际上等于module.exports .
但是,如果您将实施更改为:
math.js
在这种情况下,它可以正常工作,但是,“this”不再等于module.exports,因为创建了一个新对象 .
而现在,require要返回的是module.exports中定义的内容,而不是this或export .
另一种方法是:
math.js
要么:
math.js
Rene关于
exports
和module.exports
之间关系的答案非常清楚,它都是关于javascript引用的 . 只是想补充一点:我们在许多节点模块中看到了这一点
var app = exports = module.exports = {};
这将确保即使我们更改了module.exports,我们仍然可以通过使这两个变量指向同一个对象来使用导出 .