一、构造函数模式、混合模式、模块模式、工厂模式、单例模式、发布订阅模式的范例
- 单例模式
单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。
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');