-
定义
获取存在对象已有的属性和方法的一种方式
-
创建继承的方式
-
1、原型链继承:父类的实例作为子类的原型
function Father(name){
this.name=name;
}
Father.prototype.age=10;
function Son(name){
this.name="zzc";
}
Son.prototype=new Father();
var son=new Son();
console.log(son.name,son.age) //zzc 10
-
优点:
(1)父类新增原型方法、原型属性都能访问到
(2)简单,易于实现
-
缺点
(1)继承单一
(2)子类实例无法向父类构造函数
(3)所有新实例共享父类实例的属性(其中一个子实例修改了圆形属性,另一个子实例的原型属性也会修改)
(4)不能实现多继承
-
2、构造函数继承:复制父类的实例属性给子类
function Father(name){
this.name=name;
}
function Fathers(sex){
this.sex=sex;
}
Father.prototype.age=10;
function Son(name,sex){
Father.call(this);
Fathers.call(this)
this.name=name||"pxl"
}
var son =new Son();
console.log(son.name,son.age)
-
优点
(1)解决了子类实例共享父类引用属性的问题
(2)创建子类实例时,可以向父类传参
(3)可以实现多继承(call多个父类对象)
-
缺点
(1)只继承了父类实例的属性、方法,并未继承父类原型的属性、方法
(2)实例并不是父类的实例,只是子类的实例
(3)无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
-
3、组合继承(原型继承和构造函数继承)
function Father(name){
this.name=name
}
Father.prototype.age=10;
function Son(name){
Father.call(this);
this.name=name||"zyl"
}
Son.prototype=new Father();
Son.prototype.constructor=Son; //修复构造函数指向
var son=new Son()
console.log(son.name,son.age) //zyl 10
-
优点
(1)既可以继承父类实例的属性和方法,也可以继承父类原型的属性和方法
(2)既是子类的实例,也是父类的实例
(3)子类实例可以向父类传参
(4)函数可复用
(5)不存在父类引用属性共享
-
缺点
(1)调用了两次父类构造函数,生成了两份实例
-
4、原型式继承:为父类实例添加新属性,作为子类实例返回
function Father(name){
this.name=name;
}
Father.prototype.age=11;
function Content(name){
var instance=new Father();
instance.name=name||"zzw";
return instance;
}
var son=new Content();
console.log(son.name,son.age) //zzw 11
-
优点
(1)不限制调用方式
-
缺点
(1)不能多次调用
-
5、寄生组合继承:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点
function Father(name,age){
this.name=name||"zzj";
this.age=age||15;
}
Father.prototype.sex="女"
function Son(name,age){
Father.call(this,name,age)
}
(function(){
//创建空类
var Fathers=function(){};
//将父类原型赋值给空类
Fathers.prototype=Father.prototype;
Son.prototype=new Fathers()
})()
//修复构造函数的指向
Son.prototype.constructor=Son;
var son=new Son()
console.log(son.name,son.age,son.sex) //zzj 15 女
-
优点
(1)完美继承
-
缺点
(1)实现较为复杂