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 //使用动态原型模式,要注意一点,不可以再使用字面量的方式重写原型,因为会切断实例和新原型之间的联系。
以上就是有关原型的几种模式了,各位可以根据自己的实际情况选相应的模式。