对象具有三大特征:封装、继承、多态
继承:原型继承(父子)、构造继承(子)、实例继承(父)、组合继承(父子)
1.原型继承:将父类的实例给子类的原型上
优点:
(1)单纯的继承关系,实例是子类的实例,也是父类的实例
(2)父类新增原型方法/原型属性,子类都能访问到
(3)简单,易于实现
缺点:
(1)要想为子类新增属性和方法,必须要在父类的实例给子类的原型上之后执行
(2)不能进行多继承
(3)创建子类实例时,无法向父类构造函数传参
//父类
function Animal(){
this.name=null;
this.sex=null;
this.age=null;
this.gomove=function(){
return this.name+"会动";
}
}
//父类原型追加
Animal.prototype.catchmouse=function(){
return this.name+"会抓老鼠";
}
//子类
function Cat(){
}
//将父类的实例给子类的原型上
var an=new Animal();
Cat.prototype=an;//在这之后新添加子类属性和方法
//Cat.prototype.name="猫";
var cat=new Cat();
//cat.name="猫";
console.log(cat);
console.log(cat instanceof Animal);//true
console.log(cat instanceof Cat);//true
2.构造继承:复制父类的实例属性给子类
call(后面传递的参数是序列) apply(后面传递的参数是数组)
优点:
(1)可以实现多继承(call或者apply多个父类对象)
(2)创建子类实例时,可以向父类传递参数
缺点:
(1)实例并不是父类的实例,只是子类的实例
(2)只能继承父类的实例属性和方法,不能继承父类原型追加的属性/方法
(3)无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
//不带参数
//第一个父类
function Animal(){
this.name=null;
this.sex=null;
this.age=null;
this.gomove=function(){
return this.name+"会动";
}
}
//父类原型追加
Animal.prototype.catchmouse=function(){
return this.name+"会抓老鼠";
}
//第二个父类
function Eat(null){
this.name=null;
this.eatfood=function(){
return this.name+"吃鱼";
}
}
//子类
function Cat(){
Animal.call(this);
Eat.apply(this);
}
var cat=new Cat();
console.log(cat);
console.log(cat instanceof Animal);
console.log(cat instanceof Cat);
//带参数
//第一个父类
function Animal(name,sex){
this.name=name;
this.sex=sex;
this.age=null;
this.gomove=function(){
return this.name+"会动";
}
}
//父类原型追加
Animal.prototype.catchmouse=function(){
return this.name+"会抓老鼠";
}
//第二个父类
function Eat(name){
this.name=name;
this.eatfood=function(){
return this.name+"吃鱼";
}
}
//子类
function Cat(name,sex){
Animal.call(this,name,sex);
Eat.apply(this,[name]);
}
var cat=new Cat("猫","母");
console.log(cat);
console.log(cat.eatfood());
//console.log(cat.catchmouse());//cat.catchmouse is not a function
console.log(cat instanceof Animal);//false
console.log(cat instanceof Cat);//true
3.实例继承
优点:不限制调用方式,实例化子类还是子类调用属性和方法具有相同的效果
缺点:
(1)实例是父类的实例,不是子类的实例
(2)不支持多继承
//父类
function Animal(){
this.name=null;
this.sex=null;
this.age=null;
this.gomove=function(){
return this.name+"会动";
}
}
Animal.prototype.eat=function(){
return this.name+"吃鱼";
}
//子类
function Cat(){
var an=new Animal();
an.name="猫";
return an;
}
var c=new Cat();
c.sex="母";
console.log(c);
console.log(c.eat());
console.log(c instanceof Animal);//true
console.log(c instanceof Cat);//false
4.组合继承:(构造继承+原型继承)
优点:
(1)可以实现多继承(call或者apply多个父类对象)
(2)创建子类实例时,可以向父类传递参数
(3)单纯的继承关系,实例是子类的实例,也是父类的实例
(4)父类新增原型方法/原型属性,子类都能访问到
(5)简单,易于实现
缺点:
生成了两个实例,消耗内存;
//父类
function Animal(){
this.name=null;
this.sex=null;
this.age=null;
this.gomove=function(){
return this.name+"会动";
}
}
Animal.prototype.eat=function(){
return this.name+"吃鱼";
}
//子类
function Cat(){
Animal.call(this);//构造继承
}
Cat.prototype=new Animal();//原型继承
var c=new Cat();
console.log(c);
console.log(c.eat());
console.log(c instanceof Animal);
console.log(c instanceof Cat);