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

一、工厂模式

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/)提供的环境下使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值