JS继承的几种方法

[TOC]

JS实现继承有四种方式:
1.原型链继承
2.构造继承
3.组合继承
4.实例继承
5.拷贝继承

原型链继承

1
Child.prototype=new Parent();

原型链继承是儿子的原型是父亲的一个实例,这样儿子就能继承Parent

  • 缺点:子类的所有实例都共享着原型上的所有属性和方法。通过子类实例,可以访问原型上的属性,但是,不能重写原型上的属性。原型上引用类型的值可以通过实例进行修改,而且所有的实例访问到的该引用类型的值也会随之改变。
    *

构造继承

1
2
3
4
5
6
7
8
9
10
11
12
function Person(name,age){
this.name=name;
this.age=age;
this.eat=function(){alert("吃饭");}
}
function stu(stuId,name,age){
this.stuId=SstuId;
Person.call(this,name,age);
}
var cat = new stu(1,"wabf",22);

优点:
1.解决了原型链方式中子类实例共享父类引用属性的问题
2.创建子类实例时,可以向父类传递参数
3.可以实现多继承(call多个父类对象)

缺点:
1.实例并不是父类的实例,只是子类的实例
2.智能继承父类的实例属性和方法,不能继承父类原型属性和方法
3.无法实现函数复用,每个子类都有父类实例属性副本


组合继承

将原型继承和构造继承组合在一块,发挥二者之长
组合继承也是需要修复构造函数指向的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Person(name){
this.name=name;
}
Person.prototype.sayName=function(){
console.log(this.name);
}
function Child(name,age){
Parent.call(this,name);
this.age=age;
}
Child.prototype=new Person();
Child.pprototype.constructor=Child;//组合继承也是需要修复构造函数指向的
child1=new Child("mick",22);

  • 特点:
    弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法
    既是子类的实例,也是父类的实例
    不存在引用属性共享问题
    可传参
    函数可复用
  • 缺点:
    调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

实例继承

在子类构造函数中new父类,并为父类添加新属性,然后构造函数返回这个new的实例。

1
2
3
4
5
6
function Cat(name){
var instance=new Animal();
instance.name=name || 'Tom';
return instance;
}
var cat1=new Cat();


拷贝继承

在子类中new一个父类实例,然后遍历父类实例属性复制到子类的prototype上

1
2
3
4
5
6
7
8
9
function Cat(name){
var instance=new Animal();
for(var p in instance){
Cat.prototype[p]=instance[p];
}
Cat.prototype.name=name||"Tom";
}
var cat1=new Cat();

热评文章