JS高级学习历程-11
【继承】
在php,一个类去继承另一个类,本类实例化出来的对象,既可以调用本身类的成员,也可以调用父类的成员。
在javascript继承主要通过原型实现,构造函数继承一个对象,构造函数的实例会拥有被继承对象的相关成员。
原型继承prototype
具体实现:
1单成员继承
“构造函数”通过原型的方式继承单一的成员。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>05-原型继承</title> 6 <script type="text/javascript"> 7 //① 原型继承--“构造函数”继承单一成员 8 function Tiger(){ 9 this.color = "black and yellow"; 10 this.leg = 4; 11 this.act = function(){ 12 console.log('猛虎扑食'); 13 } 14 } 15 16 Tiger.prototype.addr = "孟加拉"; 17 18 Tiger.prototype.climb = function(){ 19 console.log('在爬树'); 20 } 21 22 var smal = new Tiger; 23 console.log(smal); 24 console.log(smal.addr); //孟加拉 25 smal.climb(); //在爬树 26 </script> 27 </head> 28 <body> 29 30 </body> 31 </html>
2对象继承
“构造函数”通过原型方式继承一个具体对象。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>06-原型继承</title> 6 <script type="text/javascript"> 7 //② 原型继承--“构造函数”继承具体对象 8 function Tiger(){ 9 this.color = "black and yellow"; 10 this.leg = 4; 11 this.act = function(){ 12 console.log('猛虎扑食'); 13 } 14 } 15 16 var cat = {eat:function(){console.log('fish')},hobby:'sleep'}; 17 18 //Tiger构造函数通过原型方式继承具体对象 19 //通过Tiger实例化出来的对象也会拥有继承对象cat的成员 20 Tiger.prototype = cat; 21 22 var north = new Tiger; 23 24 console.log(north); //color leg act eat hobby 25 north.eat(); //fish 26 console.log(north.hobby); //sleep 27 </script> 28 </head> 29 <body> 30 31 </body> 32 </html>
对象访问属性的性质和顺序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>07-对象访问属性及顺序</title> 6 <script type="text/javascript"> 7 //对象访问属性及顺序 8 function Wolf(){ 9 this.name = 'north wolf'; 10 this.fight = function(){//④ 原型对象构造函数的成员 11 console.log('多个打一个'); 12 } 13 } 14 var seven = new Wolf; 15 seven.fight = function(){ 16 console.log('7个打一个'); 17 } 18 19 function Dog(){//③ 原型对象成员seven 20 this.age = 6; 21 this.fight = function(){//② 构造函数成员 22 console.log('一个打一个'); 23 } 24 } 25 Dog.prototype = seven; 26 var yellow = new Dog; 27 28 yellow.fight = function(){//① 对象自己的成员 29 console.log('一个打多个'); 30 } 31 32 //console.log(yellow); 33 yellow.fight(); 34 35 /* 36 对象访问属性 37 ①在本对象自己成员里边寻找 38 ②如果没有,就去构造函数寻找 39 ③如果再没有,就去原型对象的成员寻找 40 ④如果再没有,就去原型对象的构造函数里边寻找 41 */ 42 </script> 43 </head> 44 <body> 45 46 </body> 47 </html>
原型链继承
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>08-原型链继承</title> 6 <script type="text/javascript"> 7 function Cat(){ 8 this.weapon = "伶牙俐齿"; 9 } 10 var kitty = new Cat; 11 12 function Tiger(){ 13 this.act = "猛虎扑食"; 14 } 15 Tiger.prototype = kitty; 16 var north = new Tiger; 17 18 function Wolf(){ 19 this.color = "gray"; 20 } 21 Wolf.prototype = north; 22 var seven = new Wolf; 23 24 function Dog(){ 25 this.leg = 4; 26 } 27 Dog.prototype = seven; 28 var smallblack = new Dog; 29 30 console.log(smallblack); 31 //console.log(smallblack.weapon); 32 33 /* 34 对象访问属性 35 ① 在对本对象自己成员里边寻找 36 ② 如果没有,就去构造函数寻找 37 ③ 如果再没有,就去原型对象的构造函数里边寻找 38 ④ 如果再没有,就去原型对象的构造函数的原型对象的成员身上寻找。。 39 实际,对象寻找成员就是在原型对象成员和构造函数内部递归寻找。 40 对象寻找成员要在对象成员和构造函数内部 41 不断向上寻找,知道找到顶端对象“Object”位置 42 整个寻找是在对个函数彼此继承的链条形状的代码里边寻找 43 我们把这个多个函数彼此集成的关系称为“原型链”,对象的属性需要在 44 这个链条的内部不断向上寻找 45 */ 46 </script> 47 </head> 48 <body> 49 50 </body> 51 </html>
原型链:多个函数彼此通过原型继承,整体形成了一个链条,这个链条成为“原型链”
原型链的顶端是Object
对象获得属性信息,要不断在 对象成员 和 构造函数内部 的原型链里边向上寻找如果没有找到就会最终找到Object位置。
判断属性的属组
对象.hasOwnProperty(属性);
返回值:true 属性是本身自己的
返回值:false 原型继承的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>09-属性属组</title> 6 <script type="text/javascript"> 7 function Dog(){ 8 this.leg = 4; 9 this.hobby = "看家护林"; 10 } 11 var seven = {eye:'闪闪发光',tail:'笔直的尾巴'}; 12 13 Dog.prototype = seven; 14 15 var black = new Dog; 16 black.eat = "吃骨头"; //本身自己的成员 17 18 //遍历对象,查看属性的归属for-in 19 for(var k in black){ 20 //hasOwnProperty()判断属性属组 21 if(black.hasOwnProperty(k)){ 22 console.log(k+'--本身成员'); 23 }else { 24 console.log(k+'--原型成员') 25 } 26 } 27 </script> 28 </head> 29 <body> 30 31 </body> 32 </html>
衍生继承
复制继承
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>10-复制继承</title> 6 <script type="text/javascript"> 7 //衍生继承---复制继承 8 function Dog(){ 9 this.leg = 4; 10 this.hobby = "看家护林"; 11 this.tail = '抬头摆尾'; 12 } 13 var seven = {eye:'闪闪发光',tail:'笔直的尾巴'}; 14 15 Dog.prototype.extend = function(obj){ 16 //把obj对象的属性复制一份给当前的对象this使用 17 for(var k in obj){ 18 //复制过来的成员必须是当前对象没有的 19 //如果当前对象没有这个属性就复制 20 if(!this.hasOwnProperty(k)){ 21 this[k] = obj[k]; 22 } 23 } 24 } 25 var black = new Dog; 26 black.extend(seven); //把seven的相关成员复制给black使用 27 console.log(black); 28 </script> 29 </head> 30 <body> 31 32 </body> 33 </html>
该复制继承非常灵活,可以根据实际需要给对象复制需要的具体成员。
总结:
- 私有成员
- 静态成员
- 原型继承
prototype
① 构造函数继承单一成员
② 构造函数继承具体对象
③ 多个构造函数可以彼此继承,形成一个继承链条,该链条成为“原型链”
原型链的顶端是Object。
4.复制继承extend