設(shè)計模式-策略模式
公司的年終獎是根據(jù)工資基數(shù)和績效來發(fā)放的。例如績效為S的員工有4倍工資。A的員工有3倍工資。B的員工有2倍工資。
基本設(shè)計:
function B(salary,level){
if('S' === level){
return 4*salary;
}else if('A' === level){
return 3*salary
}else if('B' === level){
return 2*salary
}
}
缺點:不利于進一步去拓展功能,比較危險:把核心代碼全部暴露在外面。
改進:
function PerS(salary){
return 4*salary;
}
function perA(salary){
return 3*salary;
}
function perB(salary){
return 2*salary;
}
var Obj = {
S : perS,
A: perA,
B:perB
}
function B(salary,level){
return Obj[level](salary);
}
好處:函數(shù)可以重復(fù)使用。
算法的使用和算法的實現(xiàn)分開。
設(shè)計模式-裝飾者模式
裝飾模式,也可以稱為包裝器,就是對某個對象進行再加工、使之功能增強的一種做法。
先把自己保存一個備份,再改寫自己。典型的例子jquery的ready函數(shù)。
function ready(func){
var _onload = typeof window.onload == "function" ? window.onload : function(){};
window.onload = function(){
_onload();
func();
}
}
將window.onload函數(shù)進行改寫,先將原有的onload函數(shù)保存,然后再添加用戶自定義的方法。
設(shè)計模式-單例模式
構(gòu)造器只能創(chuàng)建一個對象。當你再次去創(chuàng)建時,它會把那個已經(jīng)創(chuàng)建好對象返回給你。而不是去另一個新的對象。
function Single(name){
this.name = name
}
Single.instance = null;
Single.get = function(name){
if(!Single.instance){
Single.instance = new Single(name);
return Single.instance
}else{
return Single.instance
}
}
var s1 = Single.get('s1')
var s2 = Single.get('s2')
s1 === s2 //true
缺點:是必須要用get方法,如果是直接使用new就失去單例的特征。
var S = (function (){
var instance = null;
function Single(name){
if(instance){
return instance
}
this.name = name;
return instance = this;
}
return Single;
})()
var s1 = new S('s1');
var s2 = new S('s2');
設(shè)計模式-觀察者模式
顧名思義,就是訂閱某些功能,然后在適當?shù)臅r機發(fā)布出來,也就是執(zhí)行這些功能。
訂閱,就是把幾個函數(shù)推入數(shù)組中待用;
發(fā)布,就是把緩存在數(shù)組中的那一坨函數(shù)列隊執(zhí)行
var event = {
eventList:{},
listen:function(key,fn){
if(!this.eventList[key]){
this.eventList[key] = [];
}
this.eventList[key].push(fn);
},
remove:function(key,fn){
var fns = this.eventList[key];
if(!fns){
return false;
}
if(!fn){
//如果沒有回調(diào),表示取消此key下所有方法
fns && (fns.length=0);//這是一種快速清空數(shù)組的方法哦!
}else{
for(var i=0;i<fns.length;i++){
//遍歷方法列表,剔除需要取消的方法
//要注意fns是引用型變量,實際是去除了this.eventList[key]下的方法。
if(fns[i] == fn){
fns.splice(i,1);
}
}
}
},
//trigger('loginSucc',參數(shù)1,參數(shù)2)
trigger:function(){
//出列第一個數(shù)據(jù):'loginSucc'
var key = Array.prototype.shift.call(arguments);
var fns = this.eventList[key];//拿到一組函數(shù)
if(!fns || fns.length === 0){
//沒有要執(zhí)行的函數(shù),就返回
return false;
}
for(var i=0;i<fns.length;i++){
//arguments已經(jīng)出列了一個數(shù)據(jù),目前全是參數(shù)列表了
fns[i].apply(this,arguments);
}
}
};
var installEvent = function(obj){
for(var i in event){
obj[i] = event[i];
}
}
var login = {};
installEvent(login);
//顯示頭像
function showAvatar(){
console.log('顯示用戶頭像');
}
//顯示消息列表
function showMessage(){
console.log('顯示消息列表');
}
//訂閱
login.listen('loginSuccess',showAvatar);
login.listen('loginSuccess',showMessage);
//發(fā)布
login.trigger('loginSuccess');
//取消訂閱
login.remove('loginSuccess',showAvatar);
//再次發(fā)布
login.trigger('loginSuccess');