首页 > 代码库 > javascript——面向对象程序设计(4)
javascript——面向对象程序设计(4)
1 <script type="text/javascript"> 2 //1、继承 3 //2、原型链 4 //3、借用构造函数 5 //4、组合继承 6 //5、原型式继承 7 //6、寄生式继承 8 9 //1、继承是OO中最让人津津乐道的概念。许多OO语言都支持两种继承方式:接口继承和实现继承。 10 //接口继承只支持方法签名,而实现继承则继承实际的方法。 11 //由于函数没有签名,所以在ECMAScript中无法实现接口继承,只支持实现继承,而且其实现继承主要由原型链来实现。 12 13 //2、原型链。 14 //简单回顾一下,构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针 15 //而实例都包含一个指向原型对象的内部指针。 16 //而如果我们让原型对象指向另一个类型的实例,结果会怎样呢?显然,此时的原型对象将包含一个指向另一个原型的指针, 17 //相应的,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立, 18 //就构成了实例与原型的链条。这就是所谓原型链的基本概念。eg: 19 20 //动物类 21 function Animal() { 22 this.shout = "不知道"; 23 } 24 Animal.prototype.getAnimalValue = http://www.mamicode.com/function () { 25 return this.shout; 26 } 27 28 //狗狗类 29 function Dog() { 30 this.dogShout = "汪汪汪~"; 31 } 32 33 ///狗狗类继承动物类 34 Dog.prototype = new Animal(); 35 36 Dog.prototype.getDogValue = http://www.mamicode.com/function () { 37 return this.dogShout; 38 } 39 40 var instance = new Dog(); 41 //狗狗类调用动物类叫的方法 42 alert(instance.getAnimalValue()) 43 //instance.getAnimalValue()会经历3个步骤,1、搜索实例 2、搜索Dog.prototype 3、搜索Animal.prototype 44 //a、别忘记默认的原型。大家要记住,所有的函数的默认原型都是Object的实例,因此默认原型都会有一个内部指针, 45 //指向Object.prototype。这也正是自定义类都会继承toString()和valueOf()的方法的根本原因 46 47 48 //b、确定原型和实例的关系 49 alert(instance instanceof Object);//true 50 alert(instance instanceof Animal);//true 51 alert(instance instanceof Dog);//true 52 53 54 alert(Object.prototype.isPrototypeOf(instance));//true 55 alert(Animal.prototype.isPrototypeOf(instance));//true 56 alert(Dog.prototype.isPrototypeOf(instance));//true 57 58 //c、原型链的问题 59 //想必大家还记得,前面介绍过含引用类型值的原型会被所有的实例共享, 60 //这也是为什么要在构造函数中,而不是在原型对象中定义属性的原因。 61 //所以,实践中很少有人单独使用原型链。 62 63 64 //3、借用构造函数(又叫:伪造对象或经典继承) 65 //这种继承的方式很简单,就是在子类构造函数内部调用超类构造函数使用call或apply 66 function Animal() { 67 this.colors = [‘red‘, ‘blue‘, ‘green‘]; 68 } 69 70 function Dog() { 71 //继承了Animal类 72 Animal.call(this); 73 } 74 75 var dog = new Dog(); 76 dog.colors.push("black"); 77 alert(dog.colors);//‘red‘,‘blue‘,‘green‘,‘black‘ 78 79 var dog2 = new Dog(); 80 alert(dog2.colors);//‘red‘,‘blue‘,‘green‘ 81 82 //相对于原型链而言,借用构造函数有很大的优势,即可以在子类构造函数中向超类传递参数 83 function Animal2(name) { 84 this.name = name; 85 } 86 87 function Dog2() { 88 //继承了Animal类 89 Animal2.call(this, "大黄"); 90 this.age = 2; 91 } 92 93 var dog = new Dog2(); 94 alert("年龄:" + dog.age + ",名称:" + dog.name); 95 96 //因为方法都在构造函数中定义,因此函数复用就无从谈起了。而且在超类原型中定义的方法,对于子类型而言也是不可见的 97 //结果所有类型都只能使用构造函数模式。 98 //考虑到这些问题,借用构造函数的技术也很少单独使用。 99 100 //4、组合继承101 function Animal3(name) {102 this.name = name;103 this.colors = [‘red‘, ‘blue‘, ‘green‘];104 }105 106 Animal3.prototype.sayName = function () {107 alert(this.name)108 }109 110 function Dog3(name, age) {111 //继承属性112 Animal3.call(this, name);113 this.age = age;114 }115 //继承方法116 Dog3.prototype = new Animal3();117 Dog3.prototype.constructor = Dog3;118 Dog3.prototype.sayAge = function () {119 alert(this.age)120 }121 122 var d3 = new Dog3("小黄", 1);123 d3.colors.push("black");124 alert(d3.colors);//red,blue,green,black125 d3.sayAge();//1126 d3.sayName();//小黄127 128 //组合继承避免了原型链和借用构造函数的缺陷,融合了他们的优点,成为javascript中最常用继承方式129 //而且instanceof 和 isPrototypeOf也能够用于识别基于组合继承创建的对象。130 </script>
javascript——面向对象程序设计(4)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。