今日推荐歌曲:
in the shadow of the sun
续上篇:ES6(中)
八、ES6模块化语法
1、发展历史
- nodejs的诞生,便把JS中的最后一个问题放到了台前,即全局变量污染和依赖混乱问题。经过社区的激烈讨论,最终,形成了一个模块化方案,即鼎鼎大名的CommonJS。
- CommonJS的出现打开了前端开发者的思路。于是,开始有人想办法把CommonJS运用到浏览器中。然后,AMD规范和CMD规范相继出炉。2015年,ES6发布,它提出了官方的模块化解决方案——ES6 模块化。从此以后,模块化成为了JS本身特有的性质,这门语言终于有了和其他语言较量的资本,成为了可以编写大型应用的正式语言。
2、什么是模块化?
简单地说,大概就是随着发展,.js 文件冗余复杂,因此出现很多问题。所谓模块化就是把其拆分为多个 .js 文件,每一个 .js 文件就是一个模块,每个模块互不打扰,数据私有。
总结:
- 将程序⽂件拆分成多个⽂件,分别操作
- 拆分出来每个⽂件就是⼀个模块,模块中的数据都是私有的,模块之间互相隔离
- 通过⼀些方式,可以把模块内的指定数据导出,供其他模块使⽤。
3、模块化的作用
为了解决随着发展应用复杂度越来越高从而导致的下列问题:
- 数据私密性差
- 变量重名
- 依赖混乱
下面会用代码非常详细的介绍这些问题。
4、这些问题到底是什么?
下面是利用模块化的小案例(html文件需要js文件中的方法, c.js 文件需要 a.js 和 b.js中的方法)——
以此来说明非模块化写法的缺点:
(1)、私密性差
如下,现在需要调用 a.js 文件中的方法A1()、方法A2(),与此同此 a.js 文件中存在方法_A3(),而_A3()作为文件内部函数不希望被外部调用,那么使用之前script标签引入js文件能做到吗?
运行结果:
方法_A3()还是被调用了,原因显而易见,使用script标签引入js文件,html文件能访问整个js文件,而_A3()并未设置私密措施,html文件自然能调用不希望被调用的方法。可见这种方式私密性存在很大问题。
(2)、变量重名
当导入不同的JS文件时,如果不同文件的方法中存在相同的名字,会出现什么结果?下面的例子中,html文件先后引入 a.js 和 b.js 文件,而这两个文件中都有方法 test(),调用此方法:
运行结果:
只输出了 b.js 中的 test(),原因很简单,在引入文件时,先引入 a.js 文件,后引入 b.js 文件,后调用的 test() 覆盖了前面。
(3)、依赖混乱
现在 c.js 文件需要调用 a.js 中的方法 AC() 和 b.js 中的方法 BC(),如下:
运行结果:
- 成功调用,但这种调用存在依赖关系。
- 在html文件引入JS文件时,想要满足 c.js 调用 a.js 和 b.js 中的方法,要求a.js 和 b.js 先比 c.js被引入,这样被调用的方法才能被定义,被后者调用。
- 可在实际开发中,项目引入更多文件,几个文件很容易调整顺序,一旦这种依赖关系增多,极容易出现依赖混乱。
5、ES6 JS 模块化
现在运用模块化,依次解决上面的问题:
(1)、解决私密性差
- 如果想支持模块化的导入,需要给<script>标签添加 module 属性
- 通过 import 导入 a.js 中通过export 导出的方法
- 在导出的方法中选择需要的方法导入
- a.js 中未被导出的方法外部无法调用,保证了私密性
详情如图:
下面会介绍 import 相关内容
(2)、解决变量重名
通过 as 对 test() 进行重命名,后再调用即可,如下:
(3)、解决依赖混乱
自己直接导入所需文件中的方法,进行调用,解决了依赖问题,如下:
6、静态 import 简介
静态 import 语句用于导入由另一个模块导出的内容
(1)、导入整体模块
*
import * ...
(2)、导入单个/多个接口
导入时可以使用 as 设置别名,即可用于避免重名,也可用于设置合适的别名方便使用
//导入单个接口
import {AC} from "./a.js"
import {BC} from "./b.js"
//导入多个接口
import {A1,A2,test as A_test} from 'JS/a.js'
import {B1,B2,test as B_test} from 'JS/b.js'
(3)、导入默认接口
导入默认接口时,也可以同时导入整体/单个/多个
import myDefault from ......