媒介
都说“不反复造轮子”,就像iPhone——它除了打电话还能够播放音乐——然则工程师不必从零开始做一个音乐播放功用,或许只要在iPhone的体系中整合一个ipod。
前端开辟亦是云云,最理想化的开辟状况就是,工程师只写中心营业代码,其他通用的功用和组件都能够无缝加载他人写好的代码,就像许多那样。
但是实际情况是,有个蹩脚的 iPhone 工程师,他搞混了 iPhone 和 ipod 的体系,以至把 iPhone 的 Home 键和 iPod 的音量键焊在同一个。
另有一些蹩脚 JavaScript 开辟者,一不小心声清楚明了全局变量,杂沓了“定名空间”,都让合作开辟变得不那么友爱,抑或他开辟了一个通用模块,用户们却发明载入了他的代码以后,用户本身的代码被他搞得一团糟。
原始人写法
比方下面这段代码:
var mylove = "coding";
function getLove() {
return mylove;
}
function sayLove(thing) {
console.log(thing);
}
console.log(getLove());//>>> coding
sayLove('girl');//>>> girl
在 window 对象下声清楚明了一个变量mylove
,然后运用getLove()
函数去猎取这个变量,运用setLove()
修正这个变量。
恩,功用是完成了。只是如许做以后,说不定什么时刻你因为大意又在某个处所声清楚明了一次mylove
,而你的大意同事也不知道会在什么处所写了一个同名函数——或许有3个参数的setLove()
函数。
对象封装写法
怎么办呢?你猎取想到了,把这些变量和函数都写在一个对象里:
var loveThing = {
mylove : "coding",
getLove :function() {
return this.mylove;
},
sayLove : function(thing) {
console.log(thing);
}
}
console.log(loveThing.getLove());//>>> coding
loveThing.sayLove('girl');//>>> girl
这类写法已有点模块的模样了,一下就可以看出这几个函数和变量之间的联络。瑕玷在于一切变量都必需声明为公有,所以都要加this指导作用域以援用这些变量。更风险的是,在对象以外也能轻松变动内里的参数:
loveThing.mylove = "sleeping";
console.log(loveThing.getLove());//>>> sleeping
马上实行函数
我一直不惮以最坏的歹意忖度程序员,你永久想不到你的 partner 会不会真的在其他处所修正了你的参数,也不知道本身是不是会在不经意间修正了他的。我们必需在他动手之前——让本身的模块先实行掉,不给对方可趁之机。此时运用一种叫做马上实行函数的方法,能够防止暴露私有成员。
var loveThing = (function(){
var my = {};
var love = "coding";
my.getLove = function() {
return love;
}
my.sayLove = function(thing) {
console.log(thing);
}
return my;
})();
console.log(loveThing.getLove());//>>> coding
loveThing.sayLove('reading');//>>> reading
我们试着猎取内里的变量:
console.log(loveThing.love);//>>> undefined
果真,外部基础看不见内里的零件,只能运用供应的接口。如许才保证私有变量的平安。
放大形式
固然,一个项目要用到模块化的时刻,申明这个项目充足大充足庞杂,一个模块能够须要继续另一个模块,或许扩大模块,这时刻须要运用放大形式:
var loveThing = (function (o){
o.sayOK = function () {
console.log('OK');
};
return o;
})(loveThing);
loveThing.sayOK();//>>> OK!
宽放大形式
但是,浏览器是一个不按常理出牌的环境,你永久不知道本身援用的模块是不是已加载。万一我之前的loveThing
没有被加载,上面这段代码就会报错了(找不到对象)。解决方法就是所谓宽放大形式:
var loveThing = (function (o){
o.sayOK = function () {};
return o;
})(loveThing || {});
与之前唯一的差别就是参数能够为空对象。
至此,最基本的JavaScript模块化写法你已学会了,相信你也体会到本身本来的写法有什么不足。
受篇幅限定,本篇入门到此结束,我会鄙人一篇议论盛行的模块化范例。