常見的一些設計模式
構造函數(shù)模式(Constructor)
// 構造函數(shù)
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function () {
console.log(this.name);
};
var p1 = new Person('deejay',21);
p1.sayName();
工廠模式(factory)
工廠模式和構造函數(shù)模式每次都創(chuàng)建了一個新的引用(因為有return,每次return出來的對象引用都是不同的),創(chuàng)建出來的對象是完全不同的引用,解決了引用類型存在的問題
// 工廠模式
function createPerson(name,age) {
var person = {
name: name,
age: age,
sayName: function () {
console.log(this.name); // 這里面的this指向person
},
}
return person;
}
createPerson('deejay',21);
關于this的指向,this指向
單例模式(singleton)
創(chuàng)建了之后,就不會變了,只會指向同一個引用, 并不會創(chuàng)建一個新的對象
一般用于節(jié)約內(nèi)存,不想new一個新的對象出來的時候可以用
// 單例模式
var People = (function () { // 匿名函數(shù) 也叫l(wèi)ambda函數(shù),在js中是立即執(zhí)行的
var instance;
function init(name) {
return {
name: name,
}
}
return {
createPeople: function (name) {
if(!instance) {
instance = init(name);
}
return instance;
}
}
})();
People.createPeople('deejay');// {name: 'deejay'}
People.createPeople('hello');// {name: 'deejay'}
// 函數(shù)都是有return的,如果不寫return的是undefined,寫了就是代碼return里的東西。
//閱讀代碼的時候,一般先看函數(shù)的參數(shù)和函數(shù)的return
混合模式(mixin)
一般都是去混合原型,需要繼承的時候這么寫
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(parentPrototype) {
function F() {}; //創(chuàng)建一個空的構造函數(shù)
F.prototype = parentPrototype; //讓這個空構造函數(shù)的原型和傳入的目標原型一致
return new F(); //return出F()的實例
// 最終達到的效果就是,讓Student的原型等于Person的實例。
}
Student.prototype.sayScore = function () {
console.log(this.score);
}
var s1 = new Student('deejay',21,80);
s1.sayName();
s1.sayScore();
模塊模式(module)
通過閉包來實現(xiàn)一個模塊
// 模塊模式
var Person = (function () {
var name = 'deejay';
function sayName() {
console.log(name);
}
return {
name: name,
sayName: sayName,
}
})();
console.log(Person)
發(fā)布訂閱模式(publish / subscribe)
一般用來處理異步
// 訂閱發(fā)布模式
var EventCenter = (function () {
//以EventCenter.on('deejay',function () {console.log('deejay');})為例來分析一些代碼
var events = {}; //用來存儲所有的key/value
function on(evt,handler) {
events[evt] = events[evt] || [];
//events['deejay']此時不存在,所以events['deejay'] = [];
events[evt].push({
handler: handler
});
// events['deejay']push進去了一個處理程序
// 此時有 events['deejay'] = [{
// handlder: function () {
// console.log('deejay');
// }
// }]
}
function fire(evt,args) {
//當使用fire來啟動deejay事件時
if (!events[evt]) {//如果events['deejay']不存在,那么直接return掉
return;
}
for(var i = 0; i < events[evt].length; i++) {
//如果存在,進行遍歷,便利出events['deejay']中的所有處理程序,并且執(zhí)行
events[evt][i].handler(args);
}
}
return {
on: on,
fire: fire
}
})();
EventCenter.on('deejay',function () {
console.log('deejay');
}) //掛載一個事件deejay
EventCenter.fire('deejay');//使用fire觸發(fā)事件,輸出deejay