javascript面向对象与原型

 1 //一.工厂模式
 2   function createBox(user,age){
 3       var obj=new Object();
 4       obj.user=user;
 5       obj.age=age;
 6       obj.run=function(){
 7           return this.user+this.age+"原型在哪里!";
 8       };
 9       return obj;
10   }
11   var obj1=createBox("mly",20);
12   alert(obj1.run());
13   var obj2=createBox("zs",21);
14   alert(obj2.run());
15   alert(obj1 instanceof Object);//true
16   alert(obj2 instanceof Object);//true
17   //工厂模式缺点:不能解决对象识别问题,因为根本无法搞清楚他们到底是哪个对象的实例。
 1  //二.构造函数模式
 2   function Box(user,age){
 3     this.user=user;
 4     this.age=age;
 5     this.run=function(){
 6         return this.user+this.age+"原型在哪里!";
 7     };
 8   }
 9   var box1=new Box("mly",12);
10   alert(box1.run());
11   var box2=new Box("mly",12);
12   alert(box1.run() == box2.run()); //true,方法的值相等,因为传参一致
13   alert(box1.run == box2.run); //false,方法其实也是一种引用地址
14   //缺点:他们引用地址不同

1
//三.原型模式 2 //在原型模式声明中,多了两个属性,这两个属性都是创建对象时自动生成的。__proto__ 3 //属性是实例指向原型对象的一个指针,它的作用就是指向构造函数的原型属性constructor 4 //通过这两个属性,就可以访问到原型里的属性和方法了。

5
//模式1 6 function Box(){ 7 this.age=10; 8 } 9 Box.prototype.user="mly"; 10 Box.prototype.age=12; 11 Box.prototype.family=["哥哥","弟弟","妹妹"]; 12 Box.prototype.run=function(){ 13 return this.user+this.age+"原型在哪里!"; 14 }; 15 var box1=new Box(); 16 alert(box1.run()); 17 alert(Box.prototype.isPrototypeOf(box1));//true 证明每个实例化后对象都有原型 18 alert(box1.hasOwnProperty("user"));//false 判断user属性是否在实例对象中,false表示不再 19 alert("user" in box1)//true 只要存在实例或者原型中就返回true 20 //如何判断只在原型中呢? 21 function IsPrototype(box,para){ 22 return (!box.hasOwnProperty(para))&&(para in box); 23 } 24 alert(IsPrototype(box1,"user"));//只在原型中 25 alert(box1.age);//12 证明如果实例中有,会覆盖原型 26 alert(box1.family);//打印出:哥哥,弟弟,妹妹 27 box1.family.push("姐姐"); 28 alert(box1.family);//打印出:哥哥,弟弟,妹妹,姐姐 29 var box2=new Box(); 30 alert(box2.family);//打印出:哥哥,弟弟,妹妹,姐姐 31 //给String自定义一个方法psString 32 String.prototype.psString=function(){ 33 return this+"刚刚加的方法!"; 34 }; 35 alert("mly".psString());//打印出 mly刚刚加的方法! 36 //缺点:数据共享的缘故,当然这也是原型的优点 37 //模式2:字面量方式 38 function Desk(){} 39 Desk.prototype={ //重写原型 40 constructor:Desk,//直接强制指向Desk实例 41 user:"mly", 42 age:12, 43 run:function(){ 44 return this.user+this.age+"原型在哪里!"; 45 } 46 }; 47 var desk1=new Desk(); 48 alert(desk1.age); 49 //如果重写原型 50 Desk.prototype={ 51 age:1212 52 } 53 var desk2=new Desk(); 54 alert(desk1.run());//不报错,证明该对象已到内存中 55 alert(desk2.run());//报错 找不到run()方法,证明该原型切断了与之前的链接被重写了
 1  //四.构造函数+原型模式
 2  function Box(user,age){
 3     this.user=user;
 4     this.age=age;
 5  }
 6  Box.prototype={
 7     constructor:Box,
 8     run:function(){
 9         return this.user+this.age+"原型在这里!";
10     }
11  };
12  var box1 =new Box("mly",123);
13  alert(box1.run());//mly123原型在这里!
14  //这种混合模式很好的解决了传参和引用共享的大难题。是创建对象比较好的方法。但是你不觉得有点奇怪吗?为什么不写到一起呢?
 1  //五.动态原型模式
 2   function Box(user,age){
 3     this.user=user;
 4     this.age=age;
 5     if(typeof this.run!="function"){//原型是共享的实例化调用一次就好了,以后实例化不用调用
 6         Box.prototype.run=function(){
 7             return this.user+this.age+"动态原型模式!";
 8         };
 9     }
10   }
11   var box1=new Box("mly",123);
12   alert(box1.run());//mly123动态原型模式!
13   var box2=new Box("zs",444);
14   alert(box2.run());//zs444动态原型模式!
15   //使用动态原型模式,要注意一点,不可以再使用字面量的方式重写原型,因为会切断实例和新原型之间的联系。

以上就是有关原型的几种模式了,各位可以根据自己的实际情况选相应的模式。

原文地址:https://www.cnblogs.com/malianyong/p/3110660.html