常見的6種JavaScript設計模式
阿新 • • 發佈:2018-12-21
工廠模式:
function Animal(opts){ var obj = new Object(); obj.name = opts.name; obj.color = opts.color; obj.getInfo = function(){ return '名稱:'+obj.name +',顏色:'+ obj.color; } return obj; } var cat = Animal({name: '波斯貓', color: '白色'}); cat.getInfo();
建構函式模式:
function Animal(name, color){
this.name = name; this.color = color;
this.getName = function(){ return this.name; }
}
// 例項物件
var cat = new Animal('貓', '白色');
console.log( cat.getName() );
混合模式:
function Animal(name, color){ this.name = name; this.color = color; console.log( this.name + this.color) } Animal.prototype.getInfo = function() { console.log('名稱:'+ this.name); } function largeCat(name, color){ Animal.call(null, name, color); this.color = color; } largeCat.prototype = create(Animal.prototype); function create (parentObj){ function F(){}; F.prototype = parentObj; return newF(); }; largeCat.prototype.getColor = function(){ return this.color; } var cat = new largeCat("Persian", "白色"); console.log( cat )
模組模式:
封裝大部分程式碼,只暴露必需介面
var Car = (function(){
var name = '法拉利';
function sayName(){
console.log( name );
}
function getColor(name){
console.log( name );
}
return { name: sayName, color: getColor } })();
Car.name();
Car.color('紅色');
單例模式:
單例模式是JavaScript中最常見的一種模式,通過這種模式可以為我們提供一個名稱空間,例如jQuery庫的名稱空間為jQuery或$。名稱空間的使用是為了讓程式碼更加整潔,在多人協作開發的情況下,不同的人定義的變數很有可能重複,此時就需要使用名稱空間來約束每個人定義的變數,使相同名稱的變數放在不同的名稱空間中,避免相互干擾。
var Single = (function(){
var instance; function init() {
//define private methods and properties
//do something
return { //define public methods and properties };
}
return { // 獲取例項
getInstance:function(){
if(!instance){ instance = init(); }
return instance;
}
}
})();
var obj1 = Single.getInstance();
var obj2 = Single.getInstance();
console.log(obj1 === obj2); //true
釋出訂閱模式:
釋出—訂閱模式又叫觀察者模式,它定義了物件間一對多的關係,讓多個觀察者物件同時監聽某一個主題物件,當一個物件發生改變時,所有依賴於它的物件都將得到通知。 定義一個事件物件,它有以下功能:
監聽事件(訂閱公眾號);
觸發事件(公眾號釋出);
移除事件(取訂公眾號)
var Event = (function(){
var list = {}, listen, trigger, remove;
listen = function(key,fn){ //監聽事件函式
if(!list[key]){ list[key] = []; //如果事件列表中還沒有key值名稱空間,建立 }
list[key].push(fn); //將回調函式推入物件的“鍵”對應的“值”回撥陣列
};
trigger = function(){ //觸發事件函式
var key = Array.prototype.shift.call(arguments); //第一個引數指定“鍵”
msg = list[key];
if(!msg || msg.length === 0){
return false; //如果回撥陣列不存在或為空則返回false
}
for(var i = 0; i < msg.length; i++){
msg[i].apply(this, arguments); //迴圈回撥陣列執行回撥函式
}
};
remove = function(key, fn){ //移除事件函式
var msg = list[key];
if(!msg){ return false; //事件不存在直接返回false }
if(!fn){ delete list[key]; //若沒有後續引數,刪除整個回撥陣列
}else{ for(var i = 0; i < msg.length; i++){
if(fn === msg[i]){
msg.splice(i, 1); //刪 除特定回撥陣列中的回撥函式
}
}
}
};
return { listen: listen, trigger: trigger, remove: remove } })();
var fn = function(data){ console.log(data + '的推送訊息:xxxxxx......'); //2016.11.26的推送訊息 }
Event.listen('某公眾號', fn);
Event.trigger('某公眾號', '2016.11.26');
Event.remove('某公眾號', fn);