1. 寫出 構造函數模式、混合模式、模塊模式、工廠模式、單例模式、發布訂閱模式的范例。
-
構造函數模式
寫一個函數,把私有屬性綁定到函數內部的this
上,
把一些私有方法寫到函數的原型鏈上, 然后通過new
關鍵字來創建一個實例對象。
function Pepole(name, age) {
this.name = name;
this.age = age;
}
Pepole.prototype.sayName = funcion() {
return this.name;
};
var student = new Pepole("xsnowholy", 22);
console.log(student);
-
混合模式
建立在構造函數模式的基礎上,實現子類繼承父類的屬性和方法,子類可以在擴展屬性和方法。
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); //ES5方法,原型鏈繼承
Student.prototype = create(Person.prototype);
function create (parentObj){ // 兼容IE
function F(){}
F.prototype = parentObj;
return new F();
};
Student.prototype.sayScore = function(){
console.log(this.score);
}
var student = new Student("xsnowholy", 22, 95);
console.log(student);
-
模塊模式
使用立即執行函數包裹代碼段,使內部的私有變量和方法不會暴露出來,通過return函數給外部提供使用內部方法的接口。
這樣的好處是不會污染全局變量,外部無法訪問或者改變模塊內部的變量和方法。
var Pepole = (function(){
var name = "xsnowholy";
return {
sayName : function() {
console.log(name);
},
changeName : function(newName) {
name = newName;
}
}
})();
Pepole.sayName();
Pepole.changeName("蕭雪圣");
Pepole.sayName();
-
工廠模式
工廠模式可以算是構造函數模式的基礎版,
需要一個對象的時候可以通過這個函數創建一個對象,
但是這個對象沒有構造函數,無法用 instanceof 的方法判斷是否為實例。
function createPerson(opts){
var person = {
name: opts.name||'xsnowholy'
};
person.sayName: function(){
console.log(this.name);
}
return person;
}
var p1 = createPerson({name:'xsnowholy'});
var p2 = createPerson({name: '蕭雪圣'});
-
單例模式
單例模式就是,如果你要使用這個函數創建一個對象,如果這個對象存在則直接返回這個對象,如果對象不存在則創建這個對象。
無論你使用這個函數多少次,得到的都是同一個對象。
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();
-
發布訂閱模式
發布訂閱模式,可以自定義發布事件,事件處理函數,通過訂閱事件來觸發事件,執行函數。
var EventCenter = (function() {
var events = {};
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.length; i++) {
events[evt][i].handler(args); // 執行事件的多個方法
}
}
function off(evt) { // 刪除事件
if(!events[evt]) return;
delete events[evt];
}
return {
on: on,
fire: fire,
off: off;
}
})();
EventCenter.on("myEvent", function(data){
console.log("myEvent received...");
})
//發布事件
EventCenter.fire("myEvent");
//訂閱事件,如果該事件被添加發布過,則執行相應的函數方法
EventCenter.off("myEvent");
//刪除事件 myEvent 事件
2. 使用發布訂閱模式寫一個事件管理器,可以實現如下方式調用
Event.on('change', function(val){
console.log('change... now val is ' + val);
});
Event.fire('change', '饑人谷');
Event.off('change');
var Event = (function() {
var events = {};
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.length; i++) {
events[evt][i].handler(args); // 執行事件的多個方法
}
}
function off(evt) { // 刪除事件
if(!events[evt]) return;
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', '饑人谷'); // 訂閱事件 輸出結果: change... now val is 饑人谷
Event.off('change'); // 刪除事件