深入浅出 CommonJS

2 篇文章 0 订阅
2 篇文章 0 订阅

commonJS

一、使用

  • 导入:require

  • 导出:exports 、module.exports

二、深入解析

1.require 导入的是谁?

image-20220414200222033

由图可知 exports 实际上是将你想要暴露的所有变量、对象都作为属性挂载在exports 对象中

require函数 实际上做的事是返回指定模块的 module.exports 对象的地址指针(后面我们讲为什么导出的是module.exports)

2.exports 和 module.exports 的关系

exports === module.exports >>> true

通过上面的代码我们可以发现,exports 和 module.exports 是指向的是同一个对象

image-20220414201011292

3.node 是如何实现 exports === module.exports

我们要清楚一点 Module 是一个模块类,它用来描述一个模块文件

在 new Module() 这个类之后

const module = new Module()
const exports = {}
mudule.exports = exports

Node 将 exports 变量 赋值给了module.exports,这导致他们产生了关联

而我们最重要需要知道的一点是:require 导入的是module.exports,而不是 exports

image-20220414201748609

很残酷的是,当 module.exports 指向 exports 的时候,exports 非常有用。

当我们覆盖 module.exports 的时候,exports 就像一个小丑,不伦不类。

陷阱

如果你只打算使用 exports,那么你绝对不要直接让它指向令一个对象。

​ 因为你覆盖了 exports 它原来和 module.exports 的联系就彻底断开,你必须通过 exports 原本的引用来修改 module.exports。如果你覆盖了原本的引用,你的 module.exports 将永远指向一个空对象,除非你去修改 module.exports

bar.js
// node 初始化...
内存地址: 0x100000 -> {}
exports -> 0x100000 {}
module.exports -> 0x100000 {}

新建对象:0xb11111 -> {name:'zlx'}
// 覆盖exports
exports -> 0xb11111 {name:'zlx'}
module.exports -> 0x100000 {}

main.js
// 导入 module.exports
const bar = require(bar.js) >>> 0x100000 {}

//看吧,别覆盖 exports

4.为什么要存在 exports 这样一个鸡肋的变量?

因为 commonJS 规范上只提到 exports ,module.exports 是 node 在实现的时候的一个封装类。node 为了符合 commonJS 规范不得不做出让步,因此搞了个不伦不类的 exports。

5.总结

  • require 的返回值是 module.exports
  • module.exports 和 exports 初始化时指向同一个指针引用
  • 在只打算使用 exports 时,请不要覆盖 exports 的引用
  • exports 的存在是为了满足 commonJS 规范
  • 实战中个人觉得module.exports更加好用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值