概括:创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。
好处:通过这种方式,不仅每个实例都有自己的一份实例属性的副本,而且同时又共享着对方法的引用,最大限度的节省了内存。而且这种混合模式还支持向构造函数传递参数,可谓是集两种模式之长。
定义形式:有两种定义方式,方式-:分开定义(这样更好理解构造函数和原型),方式二:动态定义(把所有信息都封装在了构造函数中,通过在构造函数中初始化原型,又保持了同时使用构造函数和原型的有点,换句话说,可以通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型)。
应用:
方式一:分开定义,用来理解构造函数与原型
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friends=["Sandy","Court"];
}
Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name);
}
}
方式二:动态原型模式定义,避免独立的构造函数和原型,更完美的定义形式。
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friends=["xiaohonghua","xiaohuanghua"];
if(typeof this.sayName!="function"){
Person.prototype.sayName=function(){
alert(this.name);
};
}
}
- 这里的sayName()方法不存在的情况下,才会将它添加到原型中。这段代码只会在初次调用构造函数时才会执行,此后,原型已经完成初始化,不需要在做什么修改了。不过如果修改,会立即在所有实例中得到反映。
调用:
因为sayName()方法是原型方法,所以是Person实例的所有共享方法,而构造函数中定义的各种属性是各个实例的属性,随意更改,不影响其他实例。
function test(){
var person1=new Person1("xiaohong",26,"Teacher");
var person2=new Person1("xiaoming",27,"Soft Engineer");
person1.friends.push("Van");
alert(person1.friends); //xiaohonghua,xiaohuanghua,Van
alert(person2.friends); //xiaohonghua,xiaohuanghua
alert(person1.friends == person2.friends); //false
alert(person2.sayName == person2.sayName); //true
person1.sayName(); //xiaohong
}