您的位置:首页 > Web前端 > JavaScript

JS面向对象程序设计之创建对象模式

2015-09-13 11:40 621 查看

一、工厂模式

function createPerson(name,age,job){
var o=new Object();
o.name=name;
o.age=age;
o.job=job;
o.sayName=fucntion(){
alert(this.name);
};
return o;
}

var person1=createPerson("Nicholas",29,"Software Engineer");
var person2=createPerson("Greg",27,"Doctor");


优点:

抽象了创建具体对象的过程,解决了创建多个相似对象的问题

缺点:

没有解决对象识别的问题(即怎样知道一个对象的类型)

二、构造函数模式

function Person(name ,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
alert(this.name);
};
}

var person1=new Person("Nicholas",29,"Software Engineer");
var person2=new Person("Greg",27,"Doctor");


构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。任何函数,只要通过new操作符来调用,那它就可以作为构造函数,而任何函数,如果不通过new操作符来调用,那它跟普通函数也不会有什么两样。

构造函数模式的优点:

解决了对象识别的问题:Person1和Person2分别保存着Person的一个不同的实例。这两个对象又有一个constructor(构造函数)属性,该属性指向Person,如下所示:

alert(person1.constructor==Person); //true
alert(person2.constructor==Person); //true


构造函数模式的缺点:

每个方法都要在每个实例上重新创建一遍。以这种方式创建函数,会导致不同的作用域链和标识符解析,但创建Function新实例的机制仍然是相同的,然而创建两个完成同样任务的Function实例是没有必要的。

三、原型模式

function Person(){
}

Person.prototype={
constructor:Person,
name:"Nicholas",
age:29;
job:"Software Engineer",
friends:["Shelby","Court"],
sayName:function(){
alert(this.name);
}
};

var person1=new Person();
var person2=new Person();

person1.friends.push("Van");

alert(person1.friends);     //"Shelby,Court,Van"
alert(person2.friends);     //"Shelby,Court,Van"
alert(person1.friends==person2.friends);    //true


原型模式优点:

可以让所有对象实例共享它所包含的属性和方法,也就是不用在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。

原型模式缺点:

1.它省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值

2.原型模式最大的问题也是其共享的本性导致的。特别是对于包含引用属性类型值的属性,问题比较突出,比如上面代码中的person1.friends==person2.friends.

四、组合使用构造函数模式和原型模式

function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friends=["Shelby","Court"];
}
Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name);
}
};

var person1=new Person("Nicholas",29,"Software Engineer");
var person2=new Person("Greg",27,"Doctor");

person1.friends.push("Van");
alert(person1.friends);     //"Shelby,Count,Van"
alert(person2.friends);     //"Shelby,Count"
alert(person1.friends===person2.frineds);   //false
alert(person1.sayName===person2.sayName);   //true


组合模式优点:

1.每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度地节省了内存

2.这种混成模式还支持向构造函数传递参数

这种构造函数与原型混成的模式,是目前在ECMAScript 中使用最广泛、认同度最高的一种创建自定义类型的方法。可以说,这是用来定义引用类型的一种默认模式。

五、动态原型模式

function Person(name ,age, job){
//属性
this.name=name;
this.age=age;
this.job=job;
//方法
if(typeof this.sayName!="function"){
Person.prototype.sayName=function(){
alert(this.name);
}

}
}
var friend=new Person("Nicholas",29,"Software Engineer");
friend.sayName();


动态原型模式优点:

它把所有信息都封装在了构造函数中,而通过在构造函数中初始化原型(仅在必要的情况下),又保持了同时使用构造函数和原型的优点。

if语句检查的可以是初始化之后应该存在的任何属性或方法——不必用一大堆if语句检查每个属性和每个方法,只要检查其中一个即可。

注意:

在使用动态原型模式时,不能使用对象字面量重写原型。如果在已经创建了实例的情况下重写原型,那么就会切断现有实例与新原型之间的联系。

六、寄生构造函数模式

function Person(name , age , job){
var o=new Object();
o.name=name;
o.age=age;
o.job=job;
o.sayName=function(){
alert(this.name);
};
return o;
}
var friends=new Person("Nicholas",29,"Software Engineer");
friends.sayName();  //"Nicholas"


除了使用new操作符并把使用的包装函数叫做构造函数之外,这个模式跟工厂模式其实是一模一样的。构造函数在不返回值的情况下,默认会返回新对象实例。而通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值。

注意:

关于寄生构造函数模式,返回的对象与构造函数或者与构造函数的原型属性之间没有关系,也就是说,构造函数返回的对象与在构造函数外部创建的对象没什么不同。不能依赖instanceof操作符来确定对象类型。建议在可以使用其他模式的情况下,不要使用这种模式。

七、稳妥构造函数模式

function Person(name,age,job){
//创建要返回的对象
var o=new Object();

//可以在这里定义私有变量和函数

//添加方法
o.sayName=function(){
alert(name);
};
//返回对象
return o;
}

var friends=Person("Nicholas",29,"Software Engineer");
friends.sayName();      //"Nicholas"


稳妥构造函数遵循与寄生构造函数类似的模式,但有两点不同:

1.实例方法不引用this

2.不使用new操作符调用构造函数

注意:

变量friends中保存的是一个稳妥对象,而除了调用sayName()方法外,没有别的方式可以访问其数据成员。

稳妥构造函数模式提供的这种安全性,使得它非常适合在某些安全执行环境——例如,ADsafe(www.adsafe.org)和Caja(http://code.google.com/p/google-caja/)提供的环境下使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: