一、工厂模式:
function createPerson(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 person1=createPerson();
var person2=createPerson();
优点:解决大量重复创建对象问题
缺点:没有解决对象识别问题,(怎么样知道一个对象的类型)
工厂模式就是函数的应用
二、构造函数:
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
alert(this.name)
}
}
var person1=new Person();
var person2=new Person();
注意:构造函数首字母大写,实例要New 出来;
构造函数内部执行:
1.创建对象
2.将构造函数作用域赋值给对象;
3.执行构造函数的代码
4.返回对象
优点:alert(person1.constructor==Person) true
alert(person2.constructor==Person) true
alert(person1 instanceof Object ) true
alert(person1 instanceof Person) true
alert(person2 instanceof Object ) true
alert(person2 instanceof Person) true
创建了特殊Person类
每个对象都有constructol(构造函数)属性,指向该实例的构造函数
instanceof 用来检测对象是否属于后面对象类型;、
缺点:构造函数实例中的方法重复创建,每个实例的方法都不是一个方法,,浪费资源;
alert(preson1.sayName==preson2.sayName) false
三、原型模式:
function Person(){}
Person.prototype.name="Nicholas";
Person.prototype.age=29;
Person.prototype.job="Soft....";
Person.prototype.sayName=function(){
alert(this.name)
}
var person1=new Person();
person1.sayName(); //"Nicholas";
var person2=new Person();
person2.sayName(); //"Nicholas";
alert(person1.sayName==person2.sayName); //true
优点:方法是一个,
缺点:属性定义在原型上了,也是一个,不够灵活
理解原型对象:
不论什么时候,创建一个函数就会有prototype(原型)属性,属性指向他的原型对象,默认情况下所有的原型对象都自动获得一个constructor(构造函数)属性
怎么确定是否是实例与原型的关系:
alert(Person.prototype,isPrototypeOf(person1))//true
ECMA5中增加的方法getPrototypeOf()获取他的原型;
alert(Object.getPrototypeOf(person1)==Person.prototype) //true
function Person(){}
Person.prototype.name="Nicholas";
Person.prototype.age=29;
Person.prototype.job="Soft....";
Person.prototype.sayName=function(){
alert(this.name)
}
var person1=new Person();
person1.name="Liang";
alert(person1.hasOwnProprety(name)) //true
alert(person1.name) //"Liang";
var person2=new Person();
alert(person2.name) //"Nicholas"
首先会现在实例中搜索有没有查找的内容,没有再向上搜索
delete person1.name; //会删除实例中的属性
alert(person1.name) //"Nicholas";
hasOwnProperty()检测属性是否存在某个实例(判断属性是实例,还是原型)
巧妙的 in 操作符
preson1.name='xxxx';
alert(name in preson1) //判断name是否是preson的属性 true
alert(name in preson2) //判断name是否是preson的属性,不是但是原型上有 true
判断属性存在原型还是实例函数
function hasPrototypeProprety(object,name){
return !object.hasOwnProprety(name)&&(name in object)
}
更简单的原型语法
function Person(){}
Person.prototype={
constructor:Person, //一定要加,默认没有构造函数属性
name:"liang", //一次可以添加多个属性,与方法
age:"18",
job:"So......",
sayName:function(){
alert(this.name)
}
}
ECMA5可以使用defineProperty重设构造函数
object.defineProperty(Person.prototype,"constructor",{
enumerable:false,
value:Person
})
四、 最常用的组合模式:构造函数+原型模式(组合模式)
属性写在构造函数中,方法写在原型中,
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)
}
}
不同的属性,相同的方法
五、 动态原型模式
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("Liang",29,"asdasd");
friend.sayName(); //因为没有这个方法,所以创建了并使用
六、稳妥构造函数模式
没有this,new
function Person(name,age,job){
//创建要返回的对象
var o=new Object();
//在O中添加属性
o.age=age;
//在O中添加方法
o.sayName=function(){
alert(name)
}
//返回对象
return o
}
这样friend中保存的是一个稳妥对象,而除了调用sayName()方法外,没有别的方法可以访问其数据成员,不可能有别的办法访问传入到构造函数中的原始数据。稳妥模式提高了安全性、
继承:
1.原型链继承:SubType.prototype=new SuperType(); SubType原型=SuperType的实例;实例的__proto__指向所属SuperType类的原型,SubType原型指向SuperType所属累的原型
确定原型和实例的关系
alert(instance instanceOf Object); //true
alert(instance instanceOf SuberType); //true
alert(instance instanceOf SubType); //true
是否是某构造函数的实例
alert(Object.prototype.isPrototypeOf(instance)) true
alert(SuberType.prototype.isPrototypeOf(instance)) true
alert(SubType.prototype.isPrototypeOf(instance)) true
只要是原型链派生出的实例原型,都是ture