一、工厂模式
类似于现实生活中的工厂可以陈胜大量相似的商品,去做同样的事情,实现同样的效果。
原理 将原始方法封装到函数中,并返回这个对象。
优点:能解决多个相似问题。
缺点:对象类型不知道,因为typeof返回结果都为object。
function Animal(args) {
var obj = new Object();
obj.name = args.name;
obj.color = args.color;
obj.getInfo = function() {
console.log(obj.name + "; " + obj.color)
}
return obj;
}
var cat = Animal({name: 'cat', color: 'yellow'});
var dog = Animal({name: 'dog', color: 'black'});
cat.getInfo();
dog.getInfo();
console.log(typeof cat);
console.log(typeof dog);
//cat; yellow
//dog; black
//object
//object
二、构造函数模式
原理:在构造函数内使用this关键字,创建属性和方法。在用new关键词创建实例,通过传参实现不同的实例。
优点 可以识别对象类型
缺点 构造函数会重复生成函数,为每个对象都创建独立的函数版本。
function Car(color, speed, price) {
this.color = color;
this.speed = speed;
this.price = price;
this.showColor = function() {
console.log(this.color);
}
}
var car1 = new Car('yellow', '100', 100000);
var car2 = new Car('red', '150', 1300000);
console.log(car1,car2);
console.log(car1 instanceof Car) //true
//Car {color: "yellow", speed: "100", price: 100000, showColor: ƒ}
//color: "yellow"
//price: 100000
//showColor: ƒ ()
//speed: "100"
//__proto__: Object
//Car {color: "red", speed: "150", price: 1300000, showColor: ƒ}
//color: "red"
//price: 1300000
//showColor: ƒ ()
//speed: "150"
//__proto__: Object
三、单例模式
只能被实例化一次
var Single = (function() {
var instance;
function init() {
//定义私有的方法和属性
return {
//定义共有的方法和属性
}
}
return {
//获取实例
getInstance: function() {
if(!instance) {
instance = init();
}
return instance;
}
}
})()
var obj1 = Single.getInstance();
var obj2 = Single.getInstance();
console.log(obj1 === obj2)//true
四、发布-订阅者模式
发布-订阅者模式又叫观察者模式,它定义了对象间一对多的关系,让多个观察者对象同时监听某一主题对象,当发布者发生改变,所有的订阅者都会得到通知。
优点: 1、当发布者状态改变,会自动通知所有订阅者。2、发布者和订阅者耦合性降低。
缺点:1、创建订阅者需要消耗一定的事件和内存
2、虽然可以弱化对象间的关系,但是过度使用,会使得代码不好维护。
原理 1、确定发布者
2、给发布者添加缓存列表,用于存放回调函数来通知订阅者
3、发布消息,发布者遍历这个缓存列表,依次促发里面存放的订阅者回调函数。
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, 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
}
}());
var number = 1;
EventCenter.on('click', function(data){
console.log('click 事件' + data + number++ +'次');
});
EventCenter.off('click'); // 只绑定一次
EventCenter.on('click', function(data){
console.log('click 事件' + data + number++ +'次');
});
EventCenter.fire('click', '绑定');