构造函数模式创建对象
基本方法
function Person(name,age){
this.name=name;
this.age=age;
this.sayName=function(){
alert(this.name)
}
}
var p1=new Person(‘a1‘,‘b1‘);
var p2=new Person(‘a2‘,‘b2‘);
alert(p1.sayName===p2.sayName); //false
缺点
每个方法都要在每个实例上创建,由上面的代码可知p1和p2的都有一个sayName方法,但是这两个方法并不是同一个Function的实例,这样就很容易造成资源的浪费
原型模式
定义
我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的的所有实例共享的属性和方法
基本方法
function Person(){
}
Person.prototype={
constructor:Person,
name:‘fj‘,
age:10,
friends:[‘aa‘,‘bb‘],
sayName:function(){
alert(this.name);
}
}
var p1=new Person();
var p2=new Person();
p1.friend.push(‘ccc‘);
alert(p1.friends); //aa,bb,cc
alert(p2.friends); //aa,bb,cc
alert(p1.friends==p2.friends) //true
优点
解决了构造函数模式的不能将对象方法共享的弊端,让所有的对象实例共享他所包含的属性和方法。不用在构造函数中定义对象实例的信息,而是将这些信息直接添加在原型对象中
缺点
原型模式的缺点在于它的共享性,每个实力对象都将拥有相同的属性值,对于基本类型值的属性是没有多大问题的,但是对于引用类型值却是比较有较的问题,就像上面的例子一样p1和p2的frends属性是引用类型值,如果将其中的一个改变,那么另外一个也要改变
组合使用构造函数模式和原模式
定义
构造函数模式定义实例属性,原型模式用来定义方法和共享的属性
function Person(name,age){
this.name=name;
this.age=age;
this.friends=[‘aa‘,‘bb‘];
}
Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name);
}
}
var p1=new Person(‘a1‘,‘b1‘);
var p2=new Person(‘a2‘,‘b2‘);
p1.friend.push(‘ccc‘);
alert(p1.friends); //aa,bb,cc
alert(p2.friends); //aa,bb
alert(p1.friends==p2.friends) //false
alert(p1.sayName===p2.sayName); //true
优点
综合了构造函数模式和原型模式都优点,使每个实例都有自己的一份实例属性的副本,又同时共享着对方法的引用,最大的节省了内存
总结
我觉得构造函数模式就像是css中的style属性,可以为每个对象定义不同的值,而原型模式就是css中的class,可以用在每个对象上,每个对象的方法都相同,只要改变原型中的方法,所有的实例都会被改变,就像class一样,改变里面的样式,所有被引用的元素都会改变样式