Javascript模块化编程发展历史
网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等…开发者不得不使用软件工程的方法,管理网页的业务逻辑。
原始写法
只要把不同的函数简单的放在一起,就是一个模块。使用的时候,直接调用就行了
function m1(){
//执行代码
}
function m2(){
//执行代码
}
但是此种写法缺点很明显;“污染”了全局变量,无法保证不与其他模块发生变量名的冲突,而且模块成员之间看不出直接关系。
对象的写法
对象的方法解决了全局变量污染的问题,把模块写成一个对象,所有的模块成员都放在这个对象里面。但是任何对象的属性和方法,都是对外暴露的。外部可以改写对象的属性和方法。
//A同学
var moduleA = {
count: 10,
showA: function () {
this.count++;
console.log(this.count);
},
showB: function () {
this.count *= 20;
console.log(this.count);
},
};
//B同学
var moduleB = {
count: 100,
showA: function () {
this.count--;
console.log(this.count);
},
showB: function () {
this.count *= 10;
console.log(this.count);
},
};
moduleA.count = 1000; // 在外部改变A同学的count的值,内部的函数值也会随之改变
moduleA.showA(); //1001
moduleA.showB(); //20020
moduleB.showA(); //99
moduleB.showB(); //990
模块化-闭包
1、全局变量污染问题,解决
2、私有化,解决
问题:私有化:通过闭包实现的私有化。如果我想对原有的模块进行维护或者新增,不可能。
//A同学
const moduleA = (function () {
var count = 0; //私有变量
function showA() {//私有函数
count++;
console.log(count);
}
function showB() {
count *= 20;
console.log(count);
}
return {
outA: showA,
outB: showB,
};
})();
moduleA.outA(); //1
moduleA.outB(); //20
console.log(count);//报错,拿不到内部的模块的函数或属性
//B同学
放大模式
放大模式:可以对闭包实现的模块进行二次开发。
问题:加载顺序必须固定
let moduleA = (function () {
var count = 0; //私有变量
function showA() {
//私有函数
count++;
console.log(count);
}
function showB() {
count *= 20;
console.log(count);
}
return {
outA: showA,
outB: showB,
};
})();
//新增内容
moduleA = (function (mod) {
function showC() {
console.log("我是showC");
}
mod.outC = showC;
return mod;
})(moduleA);
moduleA.outA();
moduleA.outB();
moduleA.outC();
如果建2个js文件的话
例如moduleA.js
let moduleA = (function () {
var count = 0; //私有变量
function showA() {
//私有函数
count++;
console.log(count);
}
function showB() {
count *= 20;
console.log(count);
}
return {
outA: showA,
outB: showB,
};
})();
moduleA_plus.js
moduleA = (function (mod) {
function showC() {
console.log("我是showC");
}
mod.outC = showC;
return mod;
})(moduleA);
在html文件中引用时,网络控制不了,不知道哪个部分会先加载,代码就会报错
<script src="moduleA_plus.js"></script>
<script src="moduleA.js"></script>
<script>
/*
放大模式:可以对闭包实现的模块进行二次开发。
问题:加载顺序必须固定。
【注】用户在使用页面的时候,网络控制不了。
*/
moduleA.outA();
moduleA.outB();
moduleA.outC();
</script>
宽放大模式
为了解决放大模式留下的问题,第一个执行的部分有可能加载一个不存在的空对象
var moduleA = (function (mod) {
var count = 0; //私有变量
function showA() {
//私有函数
count++;
console.log(count);
}
function showB() {
count *= 20;
console.log(count);
}
mod.outA = showA;
mod.outB = showB;
return mod;
})(moduleA || {});
var moduleA = (function (mod) {
function showC() {
console.log("我是showC");
}
mod.outC = showC;
return mod;
})(moduleA || {});
moduleA.outA();
moduleA.outB();
moduleA.outC();