exports和module.exports的区别

请牢记一条原则:无论使用 exports 暴露成员,或是 module.exports 暴露成员,最终暴露的结果,都是以 module.exports 所指向的对象为准。

1.module 对象

看一下 module对象长什么样子
exports显示是未定义的undefined
在这里插入图片描述

1.module.exports 和exports 是commonjs的规范

2.export 和export default 是es6 规范

3.require 是amd规范引入方式

4.import 是es6 的一个语法标准

2.module.exports 和 exports 的联系
  • 在 module 对象中,包含 exports 属性,而我们就是通过这个属性(module.exports),向外暴露(共享)成员的。
  • exports 是 node 为了简化向外共享成员的代码,提供的一个新方式,在默认情况下,exports 和 module.exports 指向的是同一个对象(为了不混淆,你可以理解为 exports 是 module.exports 对象地址的一个引用,exports 本质是一个变量)
3.module.exports 和 exports 的区别
  • 两者没有区别,是全等的
4.module.exports 和 exports 的使用注意点(略长,但是认真看完,理解一下就懂了)
一、不恰当的使用方法:exports = xxx;
论述4.1
  1. 在使用 module.exports 时,我们可以将某一个对象赋值给 module.exports(module.exports = Object),也可以为 module.exports 挂载新属性( module.exports.name = ‘zs’),这些都没有问题,你都可以在引用的文件中拿到修改后的模块成员(module.exports 所指的对象)。
  2. 但是,如果你将某一对象或某一变量直接赋值给了 exports(例如:const project = ‘张三’; exports = project; ),那么你在引用的文件中只能拿到一个 {}。
  3. 原因是因为 exports 在默认情况下是指向 module.exports 对象的引用,如果为 exports 赋值了,那么也就是说 exports 不再指向 module.exports 所指的对象的地址,而我们向外共享成员的最终结果是 module.exports 所指的对象,如此便会导致错误。

定义两个文件做一个代码展示和说明:

//test.js
const object = { na: "name", age: 18 }
exports = object;
//main.js
const ex = require("./test")
console.log("ex", ex);

打印的结果是:这里显示是一个空的对象里面是什么都没有的在这里插入图片描述

4.2 重要结论:module.exports 和 exports 同指一个对象,但是最终暴露结果以 module.exports 的为准,上面的代码中,exports 改变了指向,而我们又没有为 module.exports 挂载任何的属性或方法,所以就拿到了空对象。
画图举例:

刚开始 module.exports 和 exports 指向同一个对象
在这里插入图片描述
然后 exports 指向了一个新对象
在这里插入图片描述
但我们向外暴露时,是以 module.exports 为标准的,也就是向外暴露的是上图中的“原对象”,而不是“新对象”,在上述代码中,我们没有对原对象做任何操作,原对象是没有值的,所以我们导入了 exports.js 之后,得到的是一个空对象。

<think>好的,我现在需要解决用户关于JavaScriptexportsmodule.exports区别的问题。首先,我需要回忆自己之前学过的相关知识,可能还需要查阅一些资料来确保准确性。 用户的问题主要集中在Node.js环境下,这两个对象的区别。我记得exportsmodule.exports的一个引用,但具体细节可能容易混淆。根据用户提供的引用,特别是引用[4]提到,exports是引用module.exports的值,改变exports时,module.exports不会改变,而模块导出的是module.exports。这似乎意味着如果直接给exports赋值,就会断开它与module.exports的联系,导致导出为空对象,如引用[1]中的例子所示。 接下来,我需要整理这些信息,形成一个清晰的解释结构。可能需要从两者的关系开始,说明初始时exports指向module.exports,这样通过exports添加属性是有效的。但一旦直接给exports赋值新对象,引用就会断开,导致后续修改无效。同时,导出始终以module.exports为准,所以直接覆盖exports不会影响导出结果。 还要注意用户提供的代码示例,比如在a.js中exports = function,结果在b.js中require得到空对象,这应该是因为exports被重新赋值,而module.exports仍然是原来的空对象,所以导出的是空对象。而正确的方式应该是修改module.exports或者保持exports的引用。 另外,需要提到常见的用法,比如导出函数或构造函数时,通常使用module.exports = ...,而导出多个方法或属性时,可以用exports.xxx = ...。同时,要强调不能混用,否则可能导致覆盖问题。 可能还需要对比两者,列出区别注意事项,帮助用户更好地理解。例如,初始关系、赋值的影响、导出结果等。最后,总结最佳实践,避免常见的错误。 需要确保回答结构清晰,分点说明,并引用提供的参考资料来支持观点。同时,要使用中文,符合用户的要求,并且按照系统级指令正确使用数学公式的格式,不过这个问题可能不太涉及数学表达式,所以可能不需要用LaTeX数学格式,但如果有代码块的话,需要用正确的格式包裹。 最后,生成相关问题,可能需要考虑常见的疑惑点,比如为什么exports有时无效,如何正确导出多个方法,或者何时选择使用exports还是module.exports。这些问题可以帮助用户进一步理解主题。</think>### JavaScript中`exports`与`module.exports`的区别 在Node.js模块系统中,`exports``module.exports`都与模块导出相关,但它们的区别联系容易引发混淆。以下是关键点解析: --- #### 1. **初始关系** - **`exports`是`module.exports`的引用**:默认情况下,Node.js将`exports`变量初始化为`module.exports`的引用。此时,通过`exports`添加属性等价于操作`module.exports`[^4]。 ```javascript // 初始状态 console.log(exports === module.exports); // true ``` --- #### 2. **赋值操作的影响** - **若直接给`exports`赋值新对象**:会切断`exports`与`module.exports`的引用关系。此后通过`exports`添加的属性将无法导出,因为模块最终导出的是`module.exports`[^1][^4]。 ```javascript // a.js exports = { name: "Alice" }; // 此时exports不再指向module.exports // b.js const a = require('./a.js'); console.log(a); // {} (module.exports仍为空对象) ``` - **若直接操作`module.exports`**:始终能正确导出内容。 ```javascript // 正确导出对象 module.exports = { name: "Bob" }; ``` --- #### 3. **导出结果的优先级** - **模块最终导出的是`module.exports`**:无论是否修改`exports`,只有`module.exports`的内容会被返回给`require()`调用[^2]。 ```javascript // 示例:混合使用(错误) exports.a = 1; module.exports = { b: 2 }; // 结果:{ b: 2 }(exports.a被覆盖) ``` --- #### 4. **常见用法对比** | 场景 | 使用`exports` | 使用`module.exports` | |--------------------------|---------------------------|----------------------------| | 导出多个属性/方法 | `exports.func = () => {}` | `module.exports.func = ...`| | 导出单一对象/构造函数 | 不适用 | `module.exports = Class` | | 动态导出 | 不适用 | 通过条件语句修改`module.exports` | --- #### 5. **最佳实践** 1. **避免混用两者**:若使用`module.exports = ...`,则不再通过`exports`添加属性。 2. **单一导出场景**:直接使用`module.exports`导出函数、类或对象。 3. **多属性导出场景**:使用`exports.xxx`或保持`module.exports`的引用一致性[^3]。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值