进阶的面向对象和原型--常见技巧
原型模式创建对象也有自己的缺点,它省略了构造函数传参初始化这一过程,带来的缺点就是初始化的值都是一致的.而原型最大的缺点就是它最大的优点,那就是共享.
原型中所有属性是被很多实例共享的,共享对于函数非常适合,对于包含基本值得属性也还可以 .但如果属性包含引用类型,就存在一定的问题
1 function Box(){}; 2 3 Box.prototype ={ 4 constructor:Box, 5 name:‘Lee‘, 6 age:100, 7 family:[‘哥哥‘,‘姐姐‘,‘妹妹‘], 8 run:function() 9 { 10 return this.name + this.age+‘运行中...‘; 11 } 12 }; 13 14 var box1 = new Box(); 15 alert(box1.family); //‘哥哥‘,‘姐姐‘,‘妹妹‘ 16 box1.family.push(‘弟弟‘); //在第一个实例修改后引用类型,保持了共享 17 18 alert(box1.family); //‘哥哥‘,‘姐姐‘,‘妹妹‘,‘弟弟‘ 19 20 //再次实例化 Box 我希望得到的是 [‘哥哥‘,‘姐姐‘,‘妹妹‘] 但是因为 共享 所以得到了[‘哥哥‘,‘姐姐‘,‘妹妹‘,‘弟弟‘] 21 var box2 = new Box(); //共享了box1添加后的引用类型的原型 22 alert(box2.family); //‘哥哥‘,‘姐姐‘,‘妹妹‘,‘弟弟‘
★为了解决这个问题,可以采用 组合构造函数+原型模式
1 function Box() 2 { 3 this.name =name ; 4 this.age =age; 5 this.family =[‘哥哥‘,‘姐姐‘,‘妹妹‘]; 6 } 7 8 Box.prototype ={ 9 constructor:Box, 10 run:function(){ 11 return this.name + this.age+‘运行中...‘; 12 } 13 14 } 15 16 var box1 =new Box(‘Lee‘,100); 17 alert(box1.family); //‘哥哥‘,‘姐姐‘,‘妹妹‘ 18 box1.family.push(‘弟弟‘); 19 alert(box1.family); //‘哥哥‘,‘姐姐‘,‘妹妹‘,‘弟弟‘ 20 21 var box2 =new Box(‘jack‘,200); 22 alert(box2.family); //‘哥哥‘,‘姐姐‘,‘妹妹‘ 23 //引用类型没有使用原型,所有没有共享
★原型模式,不管你是否调用了原型中的共享方法,它都会初始化原型中的方法,并且在声明一个对象时,
构造函数+原型部分让人感觉怪异,最好就是把构造函数和原型封装到一起。为了解决这个问题,我们可以使用动态原型模式
1 //可以将原型封装到构造函数里 2 function Box() 3 { 4 this.name =name ; 5 this.age =age; 6 this.family =[‘哥哥‘,‘姐姐‘,‘妹妹‘]; 7 8 //原型的初始化,只要第一次初始化,就可以了,没必要每次构造函数实例化的时候都初始化 9 if(typeof this.run != ‘function‘) //判断方法是否存在 10 { 11 Box.prototype.run =function() 12 { 13 return this.name + this.age+‘运行中...‘; 14 } 15 } 16 17 } 18 19 var box1 =new Box(‘Lee‘,100); 20 alert(box1.run()); 21 22 var box2 =new Box(‘jack‘,200); 23 alert(box2.run());
★★扩展:寄生构造函数=工厂模式+构造函数
1 function Box(name , age) 2 { 3 var obj =new Object(); 4 obj.name =name; 5 obj.age=age; 6 obj.run=function() 7 { 8 return this.name + this.age+‘运行中...‘; 9 } 10 return obj; 11 } 12 13 var box1 = new Box(‘Lee‘,100); 14 alert(box1.run()); 15 16 var box2 = new Box(‘jack‘,200); 17 alert(box2.run());
★★扩展:稳妥构造函数[没看出稳妥构造函数和工厂方式的区别 除了函数名首字母大写]
1 function Box(name , age) 2 { 3 var obj =new Object(); 4 obj.name =name; 5 obj.age=age; 6 obj.run=function() 7 { 8 return this.name + this.age+‘运行中...‘; 9 } 10 return obj; 11 } 12 13 var box1 =Box(‘Lee‘,100); 14 alert(box1.run()); 15 16 var box2 =Box(‘jack‘,200); 17 alert(box2.run());
时间: 2024-10-20 13:17:39