javascript-面向对象和原型(3).

进阶的面向对象和原型--常见技巧

原型模式创建对象也有自己的缺点,它省略了构造函数传参初始化这一过程,带来的缺点就是初始化的值都是一致的.而原型最大的缺点就是它最大的优点,那就是共享.
原型中所有属性是被很多实例共享的,共享对于函数非常适合,对于包含基本值得属性也还可以 .但如果属性包含引用类型,就存在一定的问题

 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(name ,age)
 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(name ,age)
 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());
原文地址:https://www.cnblogs.com/VanqusherCsn/p/4314678.html