日常的学习笔记,包括 ES6、Promise、Node.js、Webpack、http 原理、Vue全家桶,后续可能还会继续更新 Typescript、Vue3 和 常见的面试题 等等。
看过上一篇文章,我们对 require
的基本使用和其实现原理已经了解的差不多了。
通过对源码的学习,我们也会产生以下几个问题。
关于require的几个问题
首先,我们还是定义两个文件,一个导出一个引入。
1 | // 使用 require 引入文件 |
在上一篇源码分析的文章中,我们提到过这么一个点。
this = module.exports = exports
(具体可以参考我上一篇文章 require的实现)
那如果我们在这里输出 module.exports === exports
,结果又会如何呢?
module.exports、exports和this的关系
首先,我们先看一下上面那个问题的结果。
1 | // a.js |
输出的结果是 true
,我们还可以发现这三个值互换结果都是相等的。就是因为 this = module.exports = exports
。
既然他们三个是相等的,那么我是不是就可以直接 用 exports = "hello"
来输出结果了呢?
答案是不行。原因也很简单,因为我们在定义的时候是采用 let exports = module.exports = {}
的这种定义方式进行定义,文件在引用时,返回的是 module.exports
的值。 我们给 exports
赋值为 hello ,但 module.exports
依旧是空的。
1 | // 大概意思,具体实现可参考源码 |
我们既然知道了这种赋值方式不行是因为值引用的问题,那么我们很快就可以想到。 是否可以利用堆栈内存的特性,给他们绑定一个属性呢?
1 | // a.js |
我们发现,这三种形式都可以进行值的传递和引用。其含义就是 定义其堆内存中地址的值, 且修改堆的值的指向。
假设我们同时定义 module.exports
和 属性,那么结果会获取 module.exports
的值,不会获取属性。
(注:不能直接修改 this
的值,可能会发生一些错误)
1 | // a.js |
因为 module.exports
的优先级是最高的,因为最终还是将 module.exports
导出。(所以 require
方法不支持多种写法同时导出)
module.exports的简化
看过上面的定义,我们可以简单整理一下 module.exports
的简化写法。
exports简化
我们现在需要将模块内的多个值导出。
1 | // a.js |
这样写会很麻烦,所以我们可以使用 exports
来进行简化
1 | // a.js |
就是对代码进行简化。
module.exports简化
现在有多个方法需要导出,我们就可以用下面的方式简写。
1 | // a.js |
这种就是 module.exports
结合 ES6 的一种简写方式。
至此,我们的 Node的文件模块 和 Node的核心模块 就总结完毕了。
下一篇文章我会总结一下 Node中第三方模块。
本篇文章由莫小尚创作,文章中如有任何问题和纰漏,欢迎您的指正与交流。
您也可以关注我的 个人站点、博客园 和 掘金,我会在文章产出后同步上传到这些平台上。
最后感谢您的支持!