1.构造函数继承(call)
1 //父类 2 function Animal(){ 3 this.species = "动物"; 4 this.say=function(){ 5 alert(this.name) 6 } 7 } 8 //子类 9 function Cat(name,color){ 10 Animal.call(this) 11 this.name = name; 12 this.color = color; 13 } 14 var cat1 = new Cat("大毛","黄色"); 15 cat1.say();// 大毛
使用call可以绑定父类 Animal 的执行环境,使 Cat实例化的对象具有父类的属性和方法,因此.子类Cat 继承了父类Animal的属性和方法,下面我们再看一种例子:
1 //父类 2 function Animal(){} 3 Animal.prototype.species= "动物"; 4 Animal.prototype.say=function(){ 5 alert(this.name) 6 } 7 //子类 8 function Cat(name,color){ 9 Animal.call(this) 10 this.name = name; 11 this.color = color; 12 } 13 var cat1 = new Cat("大毛","黄色"); 14 cat1.say();// Uncaught TypeError: cat1.say is not a function 15 cat1.species;//undefined
说明子类用call继承父类的属性和方法只能继承父类本地的属性和方法
2.prototype继承
1 //父类 2 function Animal(){ 3 this.area="地球"; 4 } 5 Animal.prototype.species= "动物"; 6 Animal.prototype.say=function(){ 7 alert(this.name) 8 } 9 //子类 10 function Cat(name,color){ 11 this.name = name; 12 this.color = color; 13 } 14 Cat.prototype=new Animal(); 15 Cat.prototype.constructor=Cat; 16 var cat1 = new Cat("大毛","黄色"); 17 cat1.say();//大毛 18 cat1.species;//动物 19 cat1.area;//地球
父类prototype对象上的属性和方法可以这样继承,继承-2即是,因为父类实例化的对象身上既有本地的属性和方法也有原型(prototype)对象上的属性和方法,干脆就把父类的实例对象赋值给子类的prototype对象,这样子类父类的本地原型上的属性方法都继承到了.
3.直接prototype继承
1 //父类 2 function Animal(){ 3 this.area="地球"; 4 } 5 Animal.prototype.species= "动物"; 6 Animal.prototype.say=function(){ 7 alert(this.name) 8 } 9 //子类 10 function Cat(name,color){ 11 this.name = name; 12 this.color = color; 13 } 14 Cat.prototype=Animal.prototype; 15 Cat.prototype.constructor=Cat; 16 var cat1 = new Cat("大毛","黄色"); 17 cat1.say();//大毛 18 cat1.species;//动物 19 cat1.area;//undefined 20 console.log(Cat.prototype.constructor===Animal.prototype.constructor);//true 21 console.log(Cat.prototype.constructor===Cat);//true
直接prototype继承的话,父类子类的prototype都指向了同一个对象,任何对Cat.prototype的修改都会反映到Animal.prototype,这个继承也不是最佳选择.
4.利用空对象作中介
1 //父类 2 function Animal(){ 3 this.area="地球"; 4 } 5 Animal.prototype.species= "动物"; 6 Animal.prototype.say=function(){ 7 alert(this.name) 8 } 9 //子类 10 function Cat(name,color){ 11 this.name = name; 12 this.color = color; 13 } 14 15 function F(){} 16 17 F.prototype=Animal.prototype; 18 19 Cat.prototype=new F(); 20 Cat.prototype.constructor=Cat; 21 22 var cat1 = new Cat("大毛","黄色"); 23 cat1.say();//大毛 24 console.log(cat1.species);//动物 25 console.log(cat1.area);//undefined 26 console.log(Animal.prototype.constructor===Animal);//true 27 console.log(Cat.prototype.constructor===Cat);//true
可以看出只能继承父类的原型对象上属性和方法,父类本地的属性和方法没有继承到,需要继承本地原型的属性和方法可以用继承方法2,
5.拷贝继承
1 //父类 2 function Animal(){ 3 this.area="地球"; 4 } 5 Animal.prototype.species= "动物"; 6 Animal.prototype.say=function(){ 7 alert(this.name) 8 } 9 //子类 10 function Cat(name,color){ 11 this.name = name; 12 this.color = color; 13 } 14 15 16 function extend(c,p){ 17 var p=p.prototype; 18 var c=c.prototype; 19 for(var i in p){ 20 c[i]=p[i]; 21 } 22 } 23 24 extend(Cat,Animal); 25 var cat1 = new Cat("大毛","黄色"); 26 cat1.say();//大毛 27 console.log(cat1.species);//动物 28 console.log(cat1.area);//undefined 29 console.log(Animal.prototype.constructor===Animal);//true 30 console.log(Cat.prototype.constructor===Cat);//true 31 </script>
依然是原型继承,本地属性不继承
什么是面向对象?什么是继承?什么是原型?什么是原型链?
1.j面向对象:有两个层次的含义: 第一种是会使用面向对象函数; 第二种是构造面向对象函数
2.继承:派生于基类,具有基类的所有属性和方法,同时也可以定义和重新覆盖基类给的所有属性和方法,以及同时可以扩展自己的属性和方法
3.原型:javascript对象在创建的时候(除了null以外)就会与之关联的另一个对象,这个对象就是我马上所说的原型,每一个对象都会从原型"继承"属性.