- 模块模式
- 工厂模式
- 构造函数模式
- 混合模式
- 单例模式
- 发布订阅模式
模块模式
用于模块封装,用立即执行的函数嵌套一下,定义了一些私有的变量和方法,只 return 出一些供外部使用的接口,外部只能访问这些接口,无法访问私有的变量和方法
<script type="text/javascript">
var Person = (function(){
var name = "cg";
return {
changeName: function(newName){
name = newName;
},
sayName: function(){
console.log(name);
}
}
})()
Person.sayName()
Person.changeName("hello")
Person.sayName()
/*模块模式:用于模块封装,用立即执行的函数嵌套一下,定义了
一些私有的变量和方法,只 return 出一些供外部使用的接口,外
部只能访问这些接口,无法访问私有的变量和方法.
*/
</script>
工厂模式
工厂模式相当于构造函数模式的简化版,能创建对象,但是没有构造函数,无法用 instanceof
的方法判断是否为实例
<script type="text/javascript">
function createPerson(opts){
var person = {
name: opts.name || "cg"
};
person.sayName = function(){
console.log(this.name);
};
return person;
}
var p1 = createPerson({name: "cg"})
p1.sayName() //cg
var p2 = createPerson({name: "ly"})
p2.sayName() //ly
/*工厂模式相当于构造函数模式的简化版,能创建对象,
但是没有构造函数,无法用 instanceof 的方法判断是否为实例
*/
</script>
构造函数模式
构造函数模式,把私有的属性绑定到this上,把公用的方法绑定到构造函数的原型对象上,使用 new
关键词创建实例
<script type="text/javascript">
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.sayName = function(){
return this.name;
}
var student = new Person("cg", "25")
console.dir(student);
/*构造函数模式,把私有的属性绑定到this上,
把公用的方法绑定到构造函数的原型对象上,
使用 new 关键词创建实例
*/
</script>
混合模式
混合模式:子类继承父类的属性和方法,子类再绑定自己的属性和方法,是构造函数模式的扩展。
<script type="text/javascript">
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.apply(this, arguments); //Student函数继承Person函数的方法
this.score = score;
}
Student.prototype = Object.create(Person.prototype) //ES5方法,原型链继承
//以下三行代码等效 Object.create ,兼容IE
// function Fn(){}
// Fn.prototype = Person.prototype
// Student.prototype = new Fn()
Student.prototype.constructor = Student //修正构造函数
Student.prototype.sayScore = function(){
console.log(this.score)
}
var student = new Student("cg", 25, 100)
console.dir(student)
/*混合模式:子类继承父类的属性和方法,
子类再绑定自己的属性和方法
是构造函数模式的扩展。
*/
</script>
单例模式
单例模式的特点是,如果对象不存在,会初始化创建,存在后,无论调用几次,得到的永远是同一个对象
<script type="text/javascript">
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()
console.log(obj1 === obj2) //true
/*单例模式的特点是,如果对象不存在,会初始化创建,
存在后,无论调用几次,得到的永远是同一个对象
*/
</script>
发布订阅模式
发布订阅模式,可以自定义事件,绑定事件类型和处理方法,之后如果要对该事件绑定同样的方法,只要订阅该事件即可
<script type="text/javascript">
var EventCenter = (function(){
var events = {}
//发布事件,自定义一个事件以及
function addEvent(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) //执行绑定的每个方法
}
}
//删除事件,用 delete 删除 events 对象中的属性
function off(evt){
delete events[evt]
}
return {
addEvent: addEvent,
fire: fire,
off: off
}
})()
EventCenter.addEvent("myEvent", function(data){
console.log("myEvent received...");
})
//发布事件
EventCenter.fire("myEvent")
//订阅事件,如果该事件被添加发布过,则执行相应的函数方法
EventCenter.off("myEvent")
//删除事件 myEvent 事件
</script>
使用发布订阅模式写一个事件管理器,可以实现如下方式调用
Event.on('change', function(val){
console.log('change... now val is ' + val);
});
Event.fire('change', '饥人谷');
Event.off('changer');
<script type="text/javascript">
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[evt].length; i++) {
events[evt][i].handler(args)
}
}
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', '饥人谷');
//订阅事件,change... now val is 饥人谷
Event.off('change');
//删除事件
Event.fire('change', '饥人谷');
//undefined 因为 change 事件被删除了,订阅不到
</script>