一、構造函數模式、混合模式、模塊模式、工廠模式、單例模式、發布訂閱模式的范例
- 單例模式
單例就是保證一個類只有一個實例,實現的方法一般是先判斷實例存在與否,如果存在直接返回,如果不存在就創建了再返回,這就確保了一個類只有一個實例對象。
var People = (function(){
var instance;
function init() {
//define private methods and properties
//do something
return {
//define public methods and properties
};
}
return {
createPeople: function() {
if (!instance) {
instance = init();
}
return instance;
}
};
}());
var obj1 = People.createPeople();
var obj2 = People.createPeople();
- 構造函數模式
構造函數可以創建特定類型的對象
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.sayName = function(){
return this.name;
};
var student = new Person("xiaoming", 14);
- 工廠模式
在函數內創建一個對象,給對象賦予屬性及方法再將對象返回
function createPerson(opts){
var person = {
name: opts.name||'小明'
};
person.sayName: function(){
console.log(this.name);
}
return person;
}
//函數的封裝:把相同的代碼放在一個函數中
var p1 = createPerson({name:'張三'});
var p2 = createPerson({name: '李四'});
- 模塊模式
模塊模式使用了JavaScript中的一個特性-閉包
模塊模式進一步模擬了類的概念,由于閉包的存在,聲明的變量和方法只在該模式內部可用。
通過返回一個對象或變量并賦給一個函數外變量,這樣就可以暴露任何希望暴露給外界的,可以有公開和私有的方法。
var Person = (function(){
var name = 'ruoyu';
//下面函數是私有的,但可以被公開函數訪問
function sayName(){
console.log(name);
}
// 返回一個對象賦予Person
return {
name: name,
sayName: sayName
}
})();
Person.name;
Person.sayName();
- 混合模式(原型模式 + 構造函數模式)
混合模式中構造函數模式用于定義實例屬性,原型模式用于定義方法和共享屬性。
每個實例都有自己的屬性,同時又共享著方法。最大限度的節省了內存。
另外這種模式還支持傳遞初始參數。
var Person = function(name, age) {
this.name = name;
this.age = age;
};
Person.prototype.sayName = function(){
console.log(this.name);
}
var Student = function(name, age, score) {
Person.call(this, name, age);
this.score = score;
};
//Student.prototype = Object.create(Person.prototype);
Student.prototype = create(Person.prototype);
function create (parentObj){
function F(){}
F.prototype = parentObj;
return new F();
};
Student.prototype.sayScore = function(){
console.log(this.score);
}
var student = new Student(" 小明", 15, 90);
console.log(student);
- 發布訂閱模式
發布訂閱模式又叫觀察者模式,它定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都將得到通知。
var EventCenter = (function(){
var events = {};
/*
{
my_event: [{handler: function(data){xxx}}, {handler: function(data){yyy}}]
}
*/
function on(evt, handler){
events[evt] = events[evt] || [];
events[evt].push({
handler: handler
});
}
function fire(evt, args){
if(!events[evt]){
return;
}
for(var i=0; i<events[evt].length; i++){
events[evt][i].handler(args);
}
}
function off(evt){
delete events[evt]
}
return {
on: on,
fire: fire,
off: off
}
})();
EventCenter.on('my_event', function(data){
console.log('my_event received...');
});
EventCenter.on('my_event', function(data){
console.log('my_event2 received...');
});
EventCenter.fire('my_event');
EventCenter.on('change', function(val){
console.log('change... now val is ' + val);
});
EventCenter.fire('change', '饑人谷');
EventCenter.off('change');
二、使用發布訂閱模式寫一個事件管理器,可以實現如下方式調用
Event.on('change', function(val){
console.log('change... now val is ' + val);
});
Event.fire('change', '饑人谷');
Event.off('changer');
var Event=(function(){
var events={};
function on(evt,handler){
events[evt]=events[evt] || [];
events[evt].push({
handler:handler
})
}
function fire(evt,arg){
if(!events[evt]){
return
}
for(var i=0;i<events[evt].length;i++){
events[evt][i].handler(arg)
}
}
function off(evt){
delete events[evt];
}
return {
on:on,
fire:fire,
off:off
}
}());
Event.on('change', function(val){
console.log('change... now val is ' + val);
});
Event.fire('change', '饑人谷');
Event.off('changer');