js中的继承

前言

js中的继承有很多种方式,后面的方案的提出也是为了弥补前面方案的缺点,这篇文章对其做一个总结。

正文

1. 原型链继承

原型链继承的例子如下:

//原型链继承
Parent.prototype.say = function () {


  console.log('hello');


}


function Parent() {
  this.name = 'Jerry'
}





Son.prototype = new Parent() 


function Son() {
  this.age=18
}

let s1 = new Son()



console.log(s1.name);  //Jerry
console.log(s1.say());  //hello

我们可以看到打印,说明子类继承父类的所有属性和方法
如果我要实现子类给父类传参呢?我们更改下代码:

Parent.prototype.say = function () {

  console.log('hello');

}

function Parent(name) {

  this.name = name

}



Son.prototype = new Parent() 


function Son() {
  this.age=18

}




let s1 = new Son('Jerry')



console.log(s1.name);  //undefined

发现打印出来却是undefined,这说明子类是无法给父类传参的,这就引出了经典继承的方案了。

2. 经典继承

经典继承利用了call来将parent的this指向son,且将name这个参数传给parent,让子类继承到父类实例属性

//经典继承
Parent.prototype.say = function () {


  console.log('hello');


}


function Parent(name) {

  this.name = name

}





function Son(name) {
  Parent.call(this,name)   //this.name = name
  this.age=18

}




let s1= new Son('Jerry')



console.log(s1.name);   //Jerry
console.log(s1.say());  //TypeError: s1.say is not a function

可以看到经典继承弥补了原型链继承中子类不能给父类传参的缺点,但是子类能继承到父类实例上的属性,无法继承到父类原型上的属性。

3. 组合继承

组合继承可以说是前两种方案的结合,这样就可以使子类继承到父类实例上的属性和父类原型上的属性,且子类能给父类传参。

//组合继承
Parent.prototype.say = function () {


  console.log('hello');


}


function Parent(name) {

  this.name = name

}





Son.prototype = Object.create(Parent.prototype)  //继承到父类原型
function Son(name) {
  Parent.call(this, name)   //继承到父类实例属性
  this.age = 18



}



let s1 = new Son('Jerry')

console.log(s1.name);   //Jerry
console.log(s1.say());  //hello

但是,这个方案还是有些缺陷,我们放到浏览器运行并输出s1,发现s1的原型居然是parent?不应该是son吗?这就是这种方案的问题所在了。

image.png

4. 寄生组合继承

为了解决组合继承的问题所在,我们直接修改子类的原型就解决了:

Parent.prototype.say = function () {

  console.log('hello');

}

function Parent(name) {

  this.name = name

}



let proto= Object.create(Parent.prototype)  //继承到父类原型
proto.constructor =Son  //往proto对象上挂属性


Son.prototype=Object.assign(proto,Son.prototype)  //将子类的原型与父类的原型合并   
function Son(name) {
  Parent.call(this, name)   //this.name = name  继承到父类实例属性
  this.age = 18
}




let s1 = new Son('Jerry')

console.log(s1.name);   //Jerry
console.log(s1.say());  //hello

5. 类继承(ES6)

类中的继承只需用extends就能实现继承,实现方式更为优雅

class Parent {
  constructor (value) {
    this.val = value
  }
  getValue() { 
    console.log(this.val);
  }
}


class Child extends Parent {
  constructor (value) {
    super(value)
    //super(); this.val = value
  }
}




let c = new Child(1)
c.getValue()
// console.log(c);

给继承做一个简单的小总结了

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MY9vfoXw' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片