作为菜鸟,模块一词听了无数遍。最近被要求写一个简单的模块,wtf,but模块到底是个啥……(本文以我的思考过程为基础,有错请指出)
模块:就是实现特定功能的一组方法。(我觉得模块跟类相似,都是实现了一组方法,都对外暴露了访问接口。区别在于模块不需要实例化,而且模块没有构造函数)其实到这里我觉得就没必要写下去了……
一.你一定写过这样的代码
//模块
var wyc = (function(){
function getName(){
console.log("wyc");
}
function getAge(){
console.log(22);
}
return {
getName: getName,
getAge: getAge
}
})();
//访问
wyc.getName();
wyc.getAge();
这就是一个模块,你会想,我居然写过模块……别惊讶,你还写了一种设计模式——模型(模块)模式(模块和模型模式我觉得是一个意思)
二.为什么上面的就是模块了
上面,我们用到了立即执行和返回对象,先看看原始写法(没有用到上面两个)
function getName(){
console.log("wyc");
}
function getAge(){
console.log(22);
}
我们先说这两个函数实现了一个功能打印wyc的年龄22。假如后面还需要这两个函数实现另一个功能,来打印wp的年龄22。函数的调用就会乱了。
三.模块的其他写法
1.对象方法
var wyc = {
name: "wyc",
getName: function(){
console.log(this.name);
}
}
wyc.getName();
2.立即执行函数写法
1)写法一: 一.你一定写过这样的代码的例子就是一种立即执行函数的写法
2)写法二:
var wyc = (function(){
var what_I_want = "you";
var my = {};
my.name = "wyc";
my.getName = function(){
console.log(this.name);
}
my.sayWhatYouWant = function(){
console.log(what_I_want);
}
return my;
})();
wyc.getName(); //wyc
console.log(wyc.name); //wyc
wyc.sayWhatYouWant(); //you
console.log(wyc.what_I_want); //undefined
你可能会问,立即执行函数也返回了对象,和对象方法有什么区别?
区别就在上面的代码中,利用立即执行函数,可以保护我们在模块中使用但不想被外部访问的变量,比如what_I_want。
3. 放大模式/紧耦合扩充
如果一个模块需要依赖另一个模块,也就是说,这个模块需要使用另一个模块中的方法。
var wyc = (function(){
var what_I_want = "you",
my = {};
my.name = "wyc";
my.getName = function(){
return this.name;
}
my.sayWhatYouWant = function(){
return what_I_want;
}
return my;
})();
var wp = (function($){
var my = {};
$.getName = function(){
return "xxx";
}
my.hate = function(){
console.log("我讨厌"+$.getName()+",我已经不讨厌"+$.name);//我讨厌xxx,我已经不讨厌wyc
}
return my;
})(wyc);
wp.hate();
上面就是依赖wyc模块,如果wyc模块出现在wp模块之后或者没有wyc模块,都会报错
另外,wp模块重写了wyc模块的getName方法,并用到了wyc模块的name属性。
4.宽放大模式/松耦合扩充
var wp = (function($){
var my = {};
$.getName = function(){
return "xxx";
}
my.hate = function(){
console.log("我讨厌"+$.getName()+",我已经不讨厌"+$.name);//我讨厌xxx,我已经不讨厌undefined
}
return my;
})(window.wyc || {});
wp.hate();
说明:js中只有上面一个模块,也不会报错,只是和前面有wyc模块的输出不一样。
四.jquery的插件和模块之间的关系
jquery的插件就是一种紧耦合扩展jquery模块的实现。
(function ($) {
$.fn.extend({
"bold": function () {
// 加粗字体
return this.css({ fontWeight: "bold" });
}
});
})(jQuery);
jquery是可以链式调用的,但这里并不能,更多关于jquery插件请看jquery源码分析
个人写的一个jquery倒计时小插件
五.什么是模块化(名侦探柯南)
案发现场:在一个页面中实现分页功能,但是jpaginate.js在jqeury.js之前引用了……程序爆炸了
案情分析:jpaginate模块依赖jquery模块,由于javascript脚本是同步加载的。所以jpaginate获取不到jquery对象,就会报错。
有时候我们为了实现一个功能,会需要好多模块来组合实现这一功能。但是js模块之间的依赖关系,js还需要css的样式,很容易出错也不好维护修改。(比如我多个页面中用到了一堆上下依赖的js文件,我在之前又添加了一个需要依赖的js文件,那么每个页面我都要去修改一下)
模块化就是为了解决上面两个问题的
1.管理模块之间的依赖,便于模块的维护
2.实现互不依赖的js文件异步加载,避免浏览器假死
关于模块化,有几种规范,commonJS,AMD,CMD,关于模块化管理和打包工具,有webpack。
剩下的以后再写……