首先我们需要了解 JavaScript 中模块的概念,也就是模块规范啦。
现有模块规范主要有2大规范:ES6 模块规范 和 CommonJS 模块规范
AMD / CMD 模块规范均为 CommonJS 模块规范的延申版本
AMD 模块规范全称为 Asynchronous Module Definition,其代表是 RequireJS
CMD 模块规范全称为 Common Module Definition,其代表是 SeaJS
这里就不过多解释啦,有兴趣的小伙伴们可以去搜索一下。
简单介绍
ES6 即 ECMAScript 6 (版本 ECMAScript Harmony ),在2015年6月之前 JavaScript 并没有自己的模块化规范。2015年6月 ES2015 正式发布,是该语言的一个显著更新,也是自 2009 年 ES5 标准确定后的第一个重大更新。自此以后 ESCMAScript 标准一年一更新,统一使用年份命名:ES2016、ES2017、….
CommonJS 是一种规范,NodeJS是这种规范的实现。CommonJS规范的提出,主要是为了弥补JavaScript没有标准的缺陷,已达到像Python、Ruby和Java那样具备开发大型应用的基础能力,而不是停留在开发浏览器端小脚本程序的阶段。
模块 Module
在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。
为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。
现在 ES6 模块规范 和 CommonJS 模块规范也遵循这样的代码组织方式:
每一个 .js 文件就称之为一个模块
ES6 模块规范 和 CommonJS 模块规范大体趋同,但并不是说完全一样。
一个小栗子:
哪个是ES6? 哪个是 CommonJS?
没分出来?哈哈哈哈,不要着急,接下来会稍微详细说一下。
当然,有经验的小伙伴一眼就能分清了。
那我就来说明一下:
左边是ES6的语法规则,右边是CommonJS语法规则
虽然在语法的实现上形式上虽有不同,但是他们做的是同一件事。
也许你会问:“啥吖,做了啥?”
他们做的同一件事就是:
因为根据规范规定,每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类等,都是私有的,对其他文件不可见。
所以,这是将模块内部对外的接口,也就是说将想要暴露出去的内容都需要从这里导出,这样外部才能够进行访问和调用。
导出/导入
export default 和 module.exports
在简单的编码后,我们将函数 whatsThis 导出,这让函数能够在外部使用和调用。
那么应该怎么调用或使用这个函数呢?
在基本常识中,既然有导出那么相对的就是导入了。
import 和 require
为了方便比较我将代码写在了同一入口文件
在导入的语法形式上也是不尽相同,但做的也是同一件事。
将模块内部定义了对外可访问和使用的入口后,就可以通过其导入命令(代码)来导入该模块。(也许有些会将 CommonJS 的 require 称之为加载或装载,但其作用是相同的,只是在叫法上不一样)
So 那就让我们来看看上面的运行结果是什么吧!
正确输出了 whatsThis 函数里的内容
通过以上代码,我们知道 ES6 和 CommonJS 模块的导入导出在其语法形式表现上略有不同
操作 | ES6 | CommonJS |
---|---|---|
导出 | export default … | module.exports = {} |
导入 | import … form '' | require() |
至此,ES6 和 CommonJS 模块规范的导入导出基本展示完成。大家都应该有所了解了。
“但这只是基本操作,除了语法上的,那么对于这两种模块的规范有没有不同之处?”
……
那当然是有的啦,比如说 this
This
首先要了解以下几个概念(对 this 不熟悉的同学需要去补补基础课啦)
在模块中当然也有 this 概念,但是在不同的规范下他们所指向的内容却不同。
为何这么说?
那么来先看看如下代码:
你猜猜他们各自的 this 会输出什么?
……
嘻嘻嘻嘻,还是不让你们猜了。结果如下:
ES6 指向的是 undefined,CommonJS 指向的是空 Object
这是因为在各自的规范当中每一个模块都是一个独立的作用域互不干扰,所以 this 并不会因为作用提升而跳出模块的作用域。
而且,this 并没有调用者所以 this 最终指向的是 undefined。
第二个 this 指向 当前模块,是因为当前模块是其调用者,所以 this 指向了当前的模块。
那么为什么 CommonJS 的 this 是指向一个空对象呢?
因为这是由 CommonJS 规范所决定的:
所以大概知道是为什么了吧?
总结一下
说了那么多,但是并没有将两种模块规范的所有异同之处一一列举对比。
那么现在你能分清楚 exports 和 export 了吗?
参考:
http://es6.ruanyifeng.com/ http://es6.ruanyifeng.com/#docs/module http://www.zhaiqianfeng.com/2017/06/CommonJS-module-exports.html https://www.cnblogs.com/fayin/p/6831071.html
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。