1、原型链继承
父类的实列作为子类的原型
function Father( name ) {
this.name = name;
this.say = function () {
console.log( this.name + "劝你耗子尾汁" )
}
}
Father.prototype.skill = function(){
console.log( this.name + "即将释放闪电五连鞭,请注意躲避" );
}
// 父类的实列作为子类的原型
Son.prototype = new Father("马宝国")
function Son() {
}
var laoma = new Son( "老马" )
laoma.say()
laoma.skill()
控制台打印的结果为:
从打印的结果不难发现原型链继承的优缺点 :
- 优点 : 可以调用原型方法
- 缺点 :子类实例,不能向父类构造函数中传参数
2、借用构造函数继承
在子类内,使用call()调用父类方法,并将父类的this修改为子类的this.相当于是把父类的实例属性复制了一份放到子类的函数内.
function Father( name ) {
this.name = name;
this.say = function () {
console.log( this.name + "劝你耗子尾汁" )
}
}
Father.prototype.skill = function(){
console.log( this.name + "即将释放闪电五连鞭,请注意躲避" );
};
function Son() {
Father.call(this);
this.name = "马宝国";
}
var laoma = new Son()
laoma.say()
laoma.skill()
从打印的结果不难发现借用构造函数继承的优缺点 :
- 优点 :子类实例,能向父类构造函数中传参数
- 缺点 :: 不可以调用原型方法
3、组合继承
既能调用父类实例属性,又能调用父类原型属性
function Father( name ) {
this.name = name;
this.say = function () {
console.log( this.name + "劝你耗子尾汁" )
}
}
Father.prototype.skill = function(){
console.log( this.name + "即将释放闪电五连鞭,请注意躲避" );
};
Son.prototype = new Father()
function Son(name) {
Father.call(this , name);
this.name = name
}
var laoma = new Son("马宝国")
laoma.say()
laoma.skill()
es6继承
代码量少,易懂
//class 相当于es5中构造函数
//class中定义方法时,前后不能加function,全部定义在class的protopyte属性中
//class中定义的所有方法是不可枚举的
//class中只能定义方法,不能定义对象,变量等
//class和方法内默认都是严格模式
//es5中constructor为隐式属性
class People{
constructor(name='wang',age='27'){
this.name = name;
this.age = age;
}
eat(){
console.log(`${
this.name} ${
this.age} eat food`)
}
}
//继承父类
class Woman extends People{
constructor(name = 'ren',age = '27'){
//继承父类属性
super(name, age);
}
eat(){
//继承父类方法
super.eat()
}
}
let wonmanObj=new Woman('xiaoxiami');
wonmanObj.eat();
ES5继承和ES6继承的区别:
es5继承首先是在子类中创建自己的this指向,最后将方法添加到this中
Child.prototype=new Parent() || Parent.apply(this) || Parent.call(this)
es6继承是使用关键字先创建父类的实例对象this,最后在子类class中修改this