- 工厂模式
工厂模式提供一个通用的接口来创建对象。
function CarFactory (brand, price) {
var car = new Object();
car.brand = brand;
car.price = price;
car.getPrice = function () {
return this.price;
}
return car;
}
var car1 = CarFactory("牌子A", 10000);
var car2 = CarFactory("牌子B", 20000);
console.log(JSON.stringify(car1)); // {"brand":"牌子A","price":10000}
console.log(JSON.stringify(car2)); // {"brand":"牌子B","price":20000}
console.log(typeof car1); // object
console.log(typeof car2); // object
console.log(car1 instanceof Object); // true
何时使用工厂模式
当我们的对象比较复杂的时候。
当我们需要根据不同情况创建不同对象实例的时候。
当我们需要创建许多相似对象的时候。
- 单例模式
单例模式限制一个类只有一个实例化对象。
var Singleton = function(name){
this.name = name;
};
Singleton.prototype.getName = function(){
return this.name;
}
// 获取实例对象
var getInstance = (function() {
var instance = null;
return function(name) {
if(!instance) {
instance = new Singleton(name);
}
return instance;
}
})();
// 测试单例模式的实例
var a = getInstance("aa");
var b = getInstance("bb");
console.log(b.getName()); // "aa"
console.log(a === b); // true
- 代理模式
为其他对象提供一种代理以控制对这个对象的访问。
代理模式使得代理对象控制具体对象的引用。代理几乎可以是任何对象:文件,资源,内存中的对象,或者是一些难以复制的东西。
var girl = function (name) {
this.name = name;
};
// 声明男孩对象
var boy = function (girl) {
this.girl = girl;
this.sendGift = function (gift) {
alert("Hi " + girl.name + ", 男孩送你一个礼物:" + gift);
}
};
// 声明代理对象
var proxyObj = function (girl) {
this.girl = girl;
this.sendGift = function (gift) {
(new boy(girl)).sendGift(gift);
}
};
var proxy = new proxyObj(new girl("花花"));
proxy.sendGift("999朵玫瑰");
由上述代码可知,通过proxyObj进行代理,完成男孩向女孩送花的操作。因此,在代理中需要保存的是女孩的信息以及男孩送礼物的方法。
场景: 图片加载
- 装饰者模式
在不改变原对象的基础上,通过对其进行包装拓展(添加属性或方法)使原有对象可以满足用户的更复杂需求。
简单说:可以动态的给某个对象添加额外的职责,而不会影响从这个类中派生的其它对象。
//原始的飞机类
var Plan = function () {
};
Plan.prototype.fire = function () {
console.log('发射普通子弹');
};
//装饰类
var MissileDecorator = function (plan) {
this.plan = plan;
};
MissileDecorator.prototype.fire = function () {
this.plan.fire();
console.log('发射导弹!');
};
var plan = new Plan();
plan = new MissileDecorator(plan);
plan.fire();
- 发布订阅模式(观察者模式)
它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知。
var Event = (function(){
var list = {},
listen, // 订阅
trigger, // 发布
remove; // 移除
listen = function(key,fn){
if(!list[key]) {
// 如果还没有订阅过此类消息,给该类消息创建一个缓存列表
list[key] = [];
}
list[key].push(fn); // 订阅消息添加到缓存列表
};
trigger = function(){
var key = Array.prototype.shift.call(arguments), // 取出消息类型名称
fns = list[key]; // 取出该消息对应的回调函数的集合
// 如果没有订阅过该消息的话,则返回
if(!fns || fns.length === 0) {
return false;
}
for(var i = 0, fn; fn = fns[i++];) {
// 依次执行注册消息所对应的动作
fn.apply(this,arguments); // arguments 是发布消息时附送的参数
}
};
remove = function(key,fn){
var fns = list[key];
// 如果key对应的消息没有订阅过的话,则返回
if(!fns) {
return false;
}
// 如果没有传入具体的回调函数,表示需要取消key对应消息的所有订阅
if(!fn) {
fns && (fns.length = 0);
}else {
for(var i = fns.length - 1; i >= 0; i--){
var _fn = fns[i];
if(_fn === fn) {
fns.splice(i,1);// 如果存在该动作,则在消息动作序列中移除对应的动作
}
}
}
};
return {
listen: listen,
trigger: trigger,
remove: remove
}
})();
// 测试代码如下:
Event.listen("color",function(size) {
console.log("尺码为:"+size); // 打印出尺码为42
});
Event.trigger("color",42);