6.1.1 工厂模式
这种模式抽象了创建具体对象的过程。
FunctioncreatePerson(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 per=createPerson("Nicholas",29,"software");
Per.sayName();//Nicholas
6.1.2 构造函数模式
js中的构造函数可用来创建特定类型的对象。
Function Person(name,age,job){//函数名Person大写
This.name=name;
This.age=age;
This.job=job;
This.sayName=function(){
Alert(this.name);
}
};
Var per=new Person("Nicholas",29,"software");
Per.sayName();//Nicholas
构造函数与其他函数的区别就是是否用new操作符来调用。
//当做构造函数使用
Var per=new Person("Nicholas",29,"software");
Per.sayName();//Nicholas
//当做普通函数调用
Person("Greg",27,"Doctor");//添加到window
Window.sayName();//Greg
//在另一个对象的作用域中调用
Var o=new Object();
Person.call(o,"Ken",25,"Nurse");
o.sayName();//Ken
Function Person(name,age,job){//函数名Person大写
This.name=name;
This.age=age;
This.job=job;
This.sayName=sayName;//不同对象共享了在全局作用域中定义的同一个sayName()函数
}
Function sayName(){
Alert(this.name);
}
6.1.3 原型模式
我们创建的每个函数都有一个prototype(原型)属性,这个属性就是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法。
好处:原型可以让所有对象实例共享它所包含的属性和方法。
functionPerson(){
}
Person.prototype.name="Nicho";
Person.prototype.age=29;
Person.prototype.job="software";
Person.prototype.sayName=function(){
Alert(this.name);
};
Var per1=new Person();
Per1.sayName();//Nicho
Var per2=new Person();
Per2.sayName();//Nicho
//per1和per2访问的是同一组属性和同一个sayName()函数
Alert(per1.sayname==per2.sayname); //true 指针指向同一个函数
原理:
无论啥时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性。默认情况下,所有prototype属性都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性在所函数的指针。如:Person.prototype.constructor指向Person.
创建了自定义的构造函数之后,其原型属性默认只会取得constructor属性;至于其他方法都是从Object继承而来。当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型属性。在很多实现中,这个内部属性的名字是_proto_,其存在于实例与构造啊哈念书的原型属性之间,而不是存在于实例与构造函数之间。
虽然可通过对象实例访问保存在原型中的值,但不能通过对象实例重写原型中的值,相同的属性,只会屏蔽原型中的那个属性。
使用hasOwnProperty()方法可检测一个属性是存在于实例中,还是存在于原型中,存在于对象实例中时,才会返回true.
同时使用hasOwnProperty()方法和in操作符,就可以确定该属性是到底存在于对象中,还是存在于原型中,如下:
Function hasPrototypeProperty(object,name){
Return !object.hasOwnProperty(name)&&(name in object);
}
由于in操作符只有通过对象能够访问到属性就返回true,hasOwnProperty()只有在属性存在于实例中时才返回true,因此只要in操作符返回true而hasOwnProperty()返回false,就可以确定属性是原型中的属性。
简单的原型语法:
FunctionPerson(){
}
Person.prototype={
Constructor:Person,//若省略掉,将默认指向Object构造函数
Name:'Nicho',
Age:29,
Job:'software',
sayName:function(){
Alert(this.name);
}
}
原生对象的原型:如下给String基本包装类型添加一个名为startsWith()的方法:
String.prototype.startsWith=function(text){
Return this.indexOf(text)==0;
};
Var msg="Hello world!";
Alert(msg.startsWith("Hello"));//true
6.1.4 组合使用构造函数模式和原型模式
构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。
FunctionPerson(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);
}
}
6.1.5 动态原型模式
它把所有信息都封装在了构造函数中,通过在构造函数中初始化原型。
FunctionPerson(name,age,job){
//属性
This.name=name;
This.age=age;
This.job=job;
//方法
If(typeof this.sayName!="function"){
Person.prototype.sayName=function(){
Alert(this.name);
}
}
}
6.1.6 寄生构造函数模式
FunctionPerson(name,age,job){
Var o=new Object();
o.name=name;
o.age=age;
o.job=job;
o.sayName=function(){
Alert(this.name);
};
Return o;
}