您的位置:首页 > Web前端 > JavaScript

js继承的四种实现方式

2018-05-31 12:05 309 查看

一、原型链继承

核心:将父类的实例作为子类的原型。

        //声明一个动物的类
function Animal(name){
this.name=name;
this.eat=function(){
return this.name+"正在吃"
}
}
Animal.prototype.sex="公"; //父类新增原型方法/原型属性,子类都能访问到
Animal.prototype.age="3";
Animal.prototype.sleep=function(){
return this.name+"正在睡觉"
}
Animal.prototype.weight="20kg";
//声明一个子类
function dog(){

}
/* 原型链继承   直接原型一个父类*/
dog.prototype=new Animal();  //要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中无法实现多继承
dog.prototype.name="哈士奇";
dog.prototype.weight="50kg";
var Dog=new dog();//创建子类实例时,无法向父类构造函数传参
console.log(Dog.name);//哈士奇
console.log(Dog.eat());//哈士奇正在吃
console.log(Dog.sleep());//哈士奇正在睡觉
console.log(Dog.weight);//50kg
console.log(Dog instanceof dog);   //true          //实例是子类的实例,也是父类的实例
console.log(Dog instanceof Animal);//true

//动物类实例化为对象
var animal=new Animal("猫");
console.log(animal.name);
console.log(animal.eat());
console.log(animal.sex);
console.log(animal.sleep());
特点:非常纯粹的继承关系,实例是子类的实例,也是父类的实例。

          父类新增原型方法/原型属性,子类都能访问到。

          简单,易于实现。

缺点:要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中,无法实现多继承。

二、构造继承

核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

        function Animal(name,sex,age){
this.name=name;
this.sex=sex;
this.age=age;
this.eat=function(){
return this.name+"正在吃饭";
}
}
Animal.prototype.color=function(){
return "白色"
}
function Type(type){
this.type=type;
}
Type.prototype.weight=function(){
return "20kg"
}
function dog(name2,sex2,age2,type2){
Animal.apply(this);
Type.apply(this,arguments);//可以实现多继承(call多个父类对象)
this.name=name2;
this.sex=sex2;
this.age=age2;
this.type=type2;
}
var Dog=new dog("萨摩","公","3岁","犬类");//创建子类实例时,可以向父类传递参数 实例并不是父类的实例,只是子类的实例
console.log(Dog.name);//萨摩
console.log(Dog.sex);//公
console.log(Dog.age);//3岁
console.log(Dog.eat());//萨摩正在吃饭
console.log(Dog.type);//犬类
/*只能继承父类的实例属性和方法,不能继承原型属性/方法*/
/*console.log(Dog.weight());
console.log(Dog.color())*///会报错
特点:

        创建子类实例时,可以向父类传递参数

        可以实现多继承(call多个父类对象)

缺点:

        实例并不是父类的实例,只是子类的实例

        只能继承父类的实例属性和方法,不能继承原型属性/方法

        无法实现函数复用,每个子类都有父类实例函数的副本,影响性能

三、组合继承

        function Animal(name){
this.name=name;
this.eat=function (){
return this.name+"正在吃饭";
}
}
Animal.prototype.sleep=function (){
return this.name+"正在睡觉";
}
function Cat(name){
Animal.call(this,name);  //构造继承
}
//原型链继承
Cat.prototype=new Animal();
var cat=new Cat("mao");
console.log(cat.name);//mao
console.log(cat.eat());//mao正在吃饭
console.log(cat.sleep());//mao正在睡觉
特点:

        弥补了方式二的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法

        既是子类的实例,也是父类的实例

        不存在引用属性共享问题   可传参   函数可复用

缺点:调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

四、实例继承

        function Animal(name){
this.name=name;
this.eat=function (){
return this.name+"正在吃饭!";
}
}
Animal.prototype.sleep=function (){
return this.name+"正在睡觉";
}
function Cat(){
var instances=new Animal();
instances.name="mao";
return instances;
}
var cat=new Cat();
console.log(cat.name);//mao
console.log(cat.eat());//mao正在吃饭
console.log(cat.sleep());//mao正在睡觉

特点:

        不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果

缺点:

        实例是父类的实例,不是子类的实例

        不支持多继承


阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: