1.使用Object创建实例,然后为实例添加属性和方法
var person=new Object();
person.name="lalal";
person.age=28;
person.sayName=function(){alert(this.name);};
缺点:如果要创建多个person,那么就要为每个person创建相同的属性和方法,较为繁琐。
2.工厂模式
function createPerson(name,age){
var o=new Object();
o.name=name;
o.age=age;
o.sayName=function(){alert(this.name);};
return o;
}
创建对象时为:
var person1=createPerson("lalal",23);
var person2=createPerson("ninil",25);
alert(person1.sayName==person2.sayName);//false
缺点:对于每个实例,都创建了一个sayName方法,而且也不能判断实例的类型
3.构造函数模式
function CreatePerson(name,age)
{
this.name=name;
this.age=age;
this.sayName=function(){alert(this.name);};
}
创建对象时:var person1=new CreatePerson("lala",23);
但是使用这种方式只解决了判断出实例person1的类型是CreatePerson,但是对每个实例仍然还是重新创建了一个方法;
4.原型模式
构造函数的原型对象中保存了实例共享的属性或方法。
function Person(){}
Person.prototype.name="lalala";
Person.prototype.age=23;
Person.prototype.sayName=function(){alert(this.name);};
创建对象时:
var person1=new Person();
但是这样创建的实例的属性是一样的,如果属性值为基本值时,可以通过重新定义实例的同名属性来屏蔽原型中的属性;
person1.name="eowh";
person1.sayName();//"eowh"
但是如果属性值为引用值时,如果其中一个实例修改引用值,那么其他实例的引用值也会随之更改.
Person.prototype.friends=["1","2","3"];
person1.friends.push("4");
var person2=new Person();
alert(person2.friends);//1,2,3,4
对于数组型的引用值也可以通过定义实例的该属性进行屏蔽原型对象中的该属性。
5.组合构造函数和原型模式
将实例共享的属性放在构造函数中定义,而共享的方法则放在原型对象中定义
function Person(name,age)
{
this.name=name;
this.age=age;
}
Person.prototype.sayName=function(){alert(this.name);};
创建对象时:
var person1=new Person("lalal",23);
通常情况下使用这种方法来进行创建对象。且如果方法较多时,可以使用对象字面量形式来创建
Person.prototype={
constructor:Person,
sayName:function(){alert(this.name),
sayAge:function(){alert(this.age);}
}
}
但是用上述方式来写的时候,一定要记住要重新定义constructor属性,因为使用对象字面量形式来定义原型对象就是重新写了一个原型对象,而不是在创建构造函数时自动生成的原型对象了,那么新的原型对象的constructor就不再指向Person了,而且实例的[[prototype]]也不再指向原始的原型对象,而是指向了新的原型对象。
6.动态原型模式
由于学习其他面向对象语言的可能不太理解为什么将构造函数和原型对象分开,所以可以在构造函数中初始化原型对象
function Person(name,age)
{
this.name=name;
this.age=age;
if(typeof this.sayName!="function")
{
Person.prototype.sayName=function(){alert(this.name);}
}
}
这里不能使用对象字面量来定义,因为会切断实例与原型对象之间的关系,而且这里只有当初次使用Person进行创建实例时,才会判断原型对象中是否有该方法。
7.寄生构造函数模式
它与工厂模式一样,但是在创建对象时要使用new关键字,因此,它创建的实例与构造函数、构造函数的原型对象都没有关系。所以不能使用instanceof来判断对象的类型。只有在特殊情况下,我们才会使用这种方式来创建构造函数,如:我们需要使用一种特殊的数组对象,这个对象有一种特有方法,所以我们使用以下:
function SpecialArray(){
var a=new Array();
a.push.call(a,arguments);
a.toPipedString=function(){return this.join("|")};
return a;
}
创建对象时为:var a1=new SpecialArray("dfs");
8.稳妥构造函数模式
稳妥构造函数模式与寄生构造函数模式类似,但是稳妥构造函数实例对象的方法中不使用this,创建时不使用new。只有在要求安全的地方使用。
function Person(name,age)
{
var o=new Object();
o.name=name;
o.age=age;
o.sayName=function(){alert(o.name);};
return o;
}
创建时为:var person1=Person("bfdg",34);
使用instanceof操作符有效的:
构造函数模式
原型模式
组合构造函数与原型模式
动态原型模式