工厂模式
模式如下:
function cPerson(name,age){
var o=new Object();
o.name=name;
o.age=age;
o.sayName=function(){alert(this.name);};
return o;
}
var person=cPerson(“jack”,29);
缺点:没能解决对象识别问题,即person instanceof cPerson返回false。
构造器模式
模式如下:
function Person(name,age){
this.name=name;
this.age=age;
this.sayName=function(){alert(this.name);};
}
var person=new Person(“jack”,29);
与工厂模式的区别:new创建,this指向创建的对象,并且会有一个constructor属性指向构造函数;
优点:解决对象识别问题;
缺点:实例对象同名函数不相等,无法实现共享(函数复用)。
解决方案:
1.将方法移至全局作用域,不过会污染全局函数(不推荐);
2.原型。
原型模式
利用的是函数的prototype属性
模式如下:
function Person{}
Person.prototype.name=”jack”;
Person.prototype.age=29;
Person.sayName=function(){alert(this.name);};
所有实例对象共享原型中的属性和方法,原型中默认constructor属性指向构造函数。
A.prototype.isPrototypeOf(B):判断A的原型是不是B的原型;
Object.getPrototypeOf(A):获取A的原型。
代码访问属性时首相访问实例,若无,其次访问属性。
在实例中添加了一个与原型属性相同名字的属性,则有屏蔽作用。
检测实例对象是否有自己的属性:A.hasOwnProperty(“name”)。
使用in操作符检测实例或原型中是否具有该属性:“name”in A。
动态添加原型属性,无问题。动态重写整个原型对象,会切断构造函数与最初原型之间的联系。
例如:
function Person(){}
var friend=new Person();
Person.prototype={
constructor:Person,
name:”jack”,
age:20,
sayName:function(){alert(this.name);}
};
friend.sayName();//报错,实例对象指向最初的原型,没有指向重写的原型。
原型模式的问题:共享性导致,原型属性一变,所有实例会受到影响。
寄生构造函数模式
与工厂模式代码一致,不同的是创建对象时以new操作符创建对象。同样不能依赖instanceof识别对象类型。
稳妥构造函数模式
与工厂模式相似,不同的是没有使用this。同样不能依赖instanceof识别对象类型。函数内定义的属性只能由函数内的方法访问。