1、原型
所有函数都包含prototype(原型)属性,该属性是对象,所有实例共享该原型内的属性和方法。
//原型 function Person () { //构造函数 // body... } Person.prototype.name='zhangsan'; Person.prototype.age=26; Person.prototype.sayHello=function(){ return this.name+this.age+"Hello World..."; } var person1=new Person(); person1.name='lisi';
person1.age=53
var person2=new Person();
alert(person1.sayHello==person2.sayHello); //返回true,因为他们保存的是指向原型sayHello函数的指针地址(如下图右图所示),而构造函数的话此处返回false
person1.email='lisi@163.com'; //增加属性
alert(person1.hasOwnProperty("email"));//判断实例中是否存在指定属性
delete person1.name;//删除实例属性是,使其访问原型里面改属性的值
alert(person1.name);//zhangsan
delete Person.prototype.name //删除原型属性
alert(person1.name);//undefined
alert(person1.sayHello());*/
------------------------------------------也可用下面方法创建原型--------------------------------------------------------------
function Person(){
}
Person.prototype={
constructor:Person,//此处很重要,需要强制将constructor指向Person对象,默认不写的话,指向Object对象
name:"zhangsan",
age:26,
sayHello:function(){
return this.name+this.age +"Hello World.....";
}
}
PS:为什么不写constructor会指向Object?因为Person.prototype={};这种写法其实创建了一个新对象,每创建一个函数,会同时创建它的prototype,自动获取constructor属性,不重写的话constructor指向Object,重写的话,指向Person。
通过构造函数创建原型对象,不必再构造函数中定义对象信息,直接将信息添加到原型中
图解构造函数方式跟原型方式的不同:
__proto__属性是实例指向原型对象的一个指针,作用指向构造函数的原型属性constructor,通过这两个属性访问原型里的属性和方法。
原型模式的执行流程:
1.先查找构造函数实例里的属性或方法,如果有,立刻返回;
2.如果构造函数实例里面没有,则取原型对象里面查找,如果有,则返回;
原型最大的优点是实例化的所有对象都能共享属性、方法,然而这也是其最大的缺点,每个实例化对象初始化的值都是一样的,不具有独立性,如下面一段代码:
Person.prototype={ constructor:Person, name:'zhangsan', age:50, family:['父亲','母亲','哥哥'], run:function(){ return this.name+this.age+this.family; } } var person1=new Person(); person1.name='wangwu'; person1.age=60; person1.family.push('弟弟');//给person1的家庭成员加入‘弟弟’ alert(person1.family); // '父亲','母亲','哥哥','弟弟' var person2=new Person(); person2.name='lisi'; person2.age=100; alert(person2.family); // 这里也返回,'父亲','母亲','哥哥','弟弟',我们并不想让peron2的家庭成员里面也有弟弟,出现问题
解决上面问题,我们需要用到下面一种方法:组合构造函数+原型模式
2、组合构造函数+原型模式
//组合构造函数+原型模式 function Person(name,age){ //构造函数 this.name=name; this.age=age; this.family=['父亲','母亲','哥哥']; } Person.prototype={ //原型 constructor:Person, run:function(){ return this.name+this.age+this.family; } } var person1=new Person('zhangsan',10); person1.family.push('弟弟'); alert(person1.family);//'父亲','母亲','哥哥','弟弟' var person2=new Person('lisi',30); alert(person2.run());//'父亲','母亲','哥哥'
PS:这种混合模式最大的好处是解决了传参和引用共享的问题,是创建对象比较好的方法,将需要共享的属性、方法放置在原型中,独立的属性、方法在构造函数中初始化。