模块化开发
为什么要使用模块化?
在网页开发的早期,js制作作为一种脚本语言,做一些简单的表单验证或动画实现等,那个时候代码还是很少的。
- 那个时候的代码是怎么写的呢?直接将代码写在
<script>
标签中即可
随着ajax异步请求的出现,慢慢形成了前后端的分离
客户端需要完成的事情越来越多,代码量也是与日俱增。
为了应对代码量的剧增,我们通常会将代码组织在多个js文件中,进行维护。
但是这种维护方式,依然不能避免一些灾难性的问题。
- 比如全局变量同名问题:看右边的例子
另外,这种代码的编写方式对js文件的依赖顺序几乎是强制性的
但是当js文件过多,比如有几十个的时候,弄清楚它们的顺序是一件比较同时的事情。
而且即使你弄清楚顺序了,也不能避免上面出现的这种尴尬问题的发生
案例
创建一个index.html,和aaa,bbb,mmm三个js文件。
此时index.html引入小明写的aaa.js和小红写的bbb.js都是能正常起作用的
这时小明再写一个mmm.js
由于这是自己写的js文件。他知道自己在aaa.js中定义了flag=true
所以这样使用。我们在index.html中引入新写的mmm.js
由于aaa.js
和bbb.js
都定义了全局变量flag
,并且bbb.js
设置flag=false
所以此时的flag应该被bbb.js
覆盖成了false
。所以小明写的·mmm.js`中的代码是不被执行的!!
虽然我们可以把mmm.js
放在bbb.js
之前,aaa.js
之后引入
但是当js文件过多,比如有几十个的时候,弄清楚它们的顺序是一件比较同时的事情。
而且即使你弄清楚顺序了,也不能避免上面出现的这种尴尬问题的发生
匿名函数解决方案
虽然这样解决了全局变量名命名冲突覆盖的问题。但是这时mmm.js
中flag就会出现未定义。因为aaa.js
使用了匿名函数中定义的都是局部变量,需要在mmm.js
中重新定义一个flag
使用了匿名函数定义的都是局部变量,所以我们不能对代码进行复用,例如使用aaa.js
中的sum函数,这也就带来了新的问题
使用模块作为出口
我们在匿名函数的基础上定义一个对象,接收匿名函数中的所有变量和函数。将对象return出去,用一个全局变量接收。
这时我们只有在mmm.js
中通过全局变量.xx
的方式就能使用了
使用这种方式我们只要按照规定自定义自己的模块名就行了
常见的模块化规范:CommonJS、AMD、CMD,也有ES6的Modules
CommonJS
CommonJS的使用需要对其提供支持(node中使用的就是CommonJS)
导出方式
导入方式
ES6模块化
export基本使用
导出方式
import使用
导入
统一全部导入
如果我们希望某个模块中所有的信息都导入,一个个导入显然有些麻烦
通过*可以导入模块中所有的export变量
但是通常情况下我们需要给*起一个别名,方便后续的使用
export default
export default在同一个模块中,不允许同时存在多个,图上只为展示效果
不需要使用{}
导出,名字自定义。默认导入导出文件default导出的东西,因为只能存在一个export default同一模块中。