模块就是实现特定功能的一组方法
原始写法
只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块。
缺点:全局变量污染
对象写法
缺点:虽然没有造成全局变量污染,但是对外暴露,外部可以随意更改对象内的元素。
闭包(立即执行函数)
达到不暴露私有成员的目的,外部无法随意更改函数内的变量以及函数,因为根本访问不到,函数内部变量对外都是不可见的。
缺点:无法二次拓展,就是在原有基础上拓展
放大模式
缺点:拓展的基础,必须是先有一个原型,如果原型是在后面运行的,就无法拓展了
宽放大模式
解决加载顺序的问题
应用:假如两个模块js文件从外部引入,从外部引入的文件会存在异步操作,这样就造成引入模块的时间长短不一。就会出现乱序问题。
模块化开发规范
因为有了模块,我们就可以方便的使用别人的代码,想要什么功能,就加载什么模块。但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则你有你的写法,我有我的写法,这样就会乱套了。
CommonJS
适用于服务器,一般我们都是先将代码下载下来,然后引入模块,再去调用模块方法。整个过程都是同步执行的(编写代码的时候)。
声明:
module.exports={}
引入require(‘文件名’)//后缀可省略
Amd
一般用于客户端(浏览器),我们浏览器文件都是现下载。假如我们使用commonJs规范的同步执行方式,那么如果等待下载和引用的模块时间过长,那么我们程序就得卡在那无法继续运行。这样就会造成用户体验差。因此Amd一般采用的是异步执行的方式。
声明:
define(function(){
//代码
return {
//对外暴露
outA:showA,
outB:showB,
}
})
引入:(异步执行,与ajax异步操作类似)
require(['moduleA.js'],function(moduleA){
//moduleA是模块对外暴露的对象,也就是return后面的部分
//这里的代码,模块引入之后才执行。不影响后续
moudleA.outA()
moduleB.outB()
})
CMD阿里员工编写 现在不咋用了
ECM6
声明:
export={
outA:showA,
outB:showB
}
引入:(异步)
import moduleA from 'moduleA.js' //文件后缀可省略
moduleA.outA()
moduleA.outB()
require.js 模块化开发的框架
require.js是遵从Amd规范的一个模块化的js文件
作用:管理当前页面所有引入的js文件
使用: 1、 在需要做js代码规范的页面通过script标签引入require.js,并且通过script标签上的async属性(async=true),但是IE不兼容async属性,IE只兼容defer,让该js文件异步加载还需添加data-main=""设置入口文件(注:每一个.html文件都需要一个入口文件入口文件:管理当前.html页面使用的.js代码),随便创建一个js文件,将路径填入;
注:后续引入的所有.js文件,后缀都可以省略,因为require.js本来就是管理.js文件的,在使用.js后缀就显得多余了。
2、 创建新的js文件,每个js文件对应一个模块,每个模块必须遵守AMD规范;
3、 在刚刚script标签的data-main属性设置的入口文件中,引入模块使用AMD规范引入;
在我们引入模块的过程中,如果需要引入多个模块的话,那么就路径引入起来就比较繁琐。我们可以通过配置路径,就没必要在引入模块的时候再写路径了。
配置路径:
require.config({
path:{
自定义模块的名字:引入模块的路径
}
})
当我们需要在一个模块中引入另一个模块的方法时,我们在需要引入另外模块的方法的模块中的define添加与require一样的参数以及形参。参数也是根据是否配置路径而定
有两种情况:
第一种:假如我们没有配置路径,而是使用原来的方式引入路径的话。第一个数组的参数必须填写引入相应模块的路径
第二种:已经在入口文件配置路径,第一个数组的参数填写在入口文件自定义的路径名即可
注:一个html页面只需要一个入口文件,这个入口文件专门去管理所有引入的js文件。也就是说,当我们使用了模块化开发以后,整个页面只能有一个script标签。多个页面必须使用多个入口文件,并且入口文件不能够重名。路径配置与不配置路径是有较大的区别,最好是去配置路径,这样即使是冗长的路径也只需要在引入时填写自定义的路径名即可。
模块化开发案例:
缩放和拖拽
github地址: https://github.com/lijia-bb/module.git