之前看过几篇关于exports、module.exports感觉都说的不清不楚,作为菜鸟,今天看了node.js实战后,才彻底搞清楚他们之间的区别,故在此分享下书中关于这两个对象/变量的区别,大佬就略过吧,哈哈)。 为了保持原汁原味,我就先把原文关于exports和module.exports区别搬过来,后面有更深的理解再做解析、分析,希望能帮助到和我一样的初学者。 原文:Node 模块允许从被引入文件中选择要暴露给程序的函数和变量。如果模块返回的函数或变量不止一个,那它可以通过设定 exports 对象的属性来指明它们。但如果模块只返回一个函数或变量,则可以设定 module.exports 属性。 代码实例exports: const canadianDollar = 0.91; function roundTwo(amount) { return Math.round(amount * 100) / 100; } exports.canadianToUS = canadian => roundTwo(canadian * canadianDollar); *exports.USToCanadian = us => roundTwo(us / canadianDollar); *
exports 对象上只设定了两个属性。也就是说引入这个模块的代码只能访问到 canadianToUS 和 USToCanadian 这两个函数。而变量 canadianDollar 作为私有变量仅作用在canadianToUS 和 USToCanadian 的逻辑内部,程序不能直接访问它。
尽管用函数和变量组装 exports 对象能满足大多数的模块创建需要,但有时你可能需要用不同的模型创建该模块。比如说,前面创建的那个货币转换器模块可以改成只返回一个 Currency 构造函数,而不是包含两个函数的对象。
要创建只返回一个变量或函数的模块,你可能会以为只要把 exports 设定成你想返回的东西就行。但这样是不行的,因为 Node 觉得不能用任何其他对象、函数或变量给 exports 赋值。下面这个代码中的模块代码试图将一个函数赋值给 exports。
**错误**代码示例:
class Currency {
constructor(canadianDollar) {
this.canadianDollar = canadianDollar;
}
roundTwoDecimals(amount) {
return Math.round(amount * 100) / 100;
}
canadianToUS(canadian) {
return this.roundTwoDecimals(canadian * this.canadianDollar);
}
USToCanadian(us) {
return this.roundTwoDecimals(us / this.canadianDollar);
}
}
exports = Currency; //错误的方式,将会报错
为了让前面那个模块的代码能用,需要把 exports 换成 module.exports。用 module.exports 可以对外提供单个变量、函数或者对象。如果你创建了一个既有 exports 又有module.exports 的模块,那它会返回 module.exports,而 exports 会被忽略。
注意:最终在程序里导出的是 module.exports。exports 只是对 module.exports 的一个全局引用,最初被定义为一个可以添加属性的空对象。exports.myFunc 只是 module.exports.myFunc 的简写。所以,如果把 exports 设定为别的,就打破了 module.exports 和 exports 之间的引用关系。可是因为真正导出的是 module.exports,那样 exports 就不能用了,因为它不再指向module.exports 了。如果你想保留那个链接,可以像下面这样让 module.exports 再次引用
exports:module.exports = exports = Currency;
根据需要使用 exports 或 module.exports 可以将功能组织成模块,规避掉程序脚本一直增长所产生的弊端。
补充: 1.module.exports 初始值为一个空对象 {} 2.exports 是指向的 module.exports 的引用 3.require() 返回的是 module.exports 而不是 exports 记住这三点,就明白了