JS中的继承

所谓的继承,按我们所认识的就是儿子继承父亲的产业之类的;在我们js中也是,子类继承父类的属性和方法;js中的继承又分为以下几类,接下来,让我们一起看看js中的继承方式吧

1.原型链继承

原理

1.让子的原型指向付的实例

2.让子的constructor重新指向子

代码演示

//父
//
function Father(x){
  this.x=x
}
//公有属性
Father.prototype.getX=function(){
    console.log('getX',this.x)
}
this.name="aaa" //也是私有属性
let f=new Father(x=100)
//子
//
function Son(x){
  this.y=y
}
//
//直接将父的实例 赋值给子的原型;实现继承;要先写,否则没法给子上面挂载方法
//
Son.prototype=new Father(x=100)
//让子类的constructor的重新指向子;因为此时子的prototype指向的是父的--proto--
Son.prototype.constructor=Son
//
Son.prototype.getX=function(){}
let s=new Son(y=200)

特点

1). JS继承不像其他语言中的继承一样(其他语言:子继承父类,就是拷贝一份父类的属性和方法),js中是把父类的实例放到子类的原型链上,子类的实例想要调用这些属性和方法的时候,实际上是基于proto原型链查找的形式去完成

2). 子类实例可以直接修改父类的属性和方法(这样会导致其他父类的实例会受到影响)子改变 了,但父没有跟着变

3). 父类的私有属性和方法,在实现原型链继承之后都会变成子类的公有属性和方法(因为是将父的实例化,赋值给子的prototype)

运行机制

 2.call继承

原理

在子的方法中,把父 当做普通函数执行,让父中的this指向子的实例,相当于给子设置了私有属性和方法

代码演示

//父类
function F(x){
   this.x=x
}
F.prototype.getX=function(){}
let f=new F(x=100)
//
//子类
function S(y){
  this.y=y

  //借用call,将this指向从window变为子的实例s

  F.call(this,传给父类的参数x)

  //
}

let s=new S(y=200)

特点

1).只能继承父类的私有属性和方法(因为只是将父当做普通函数执行了一次,跟父上面的原型没有关系,所以在子中不能调用父中prototype上的方法)

2). 父类的私有属性和方法都会变成子类的私有属性和方法(解决了 原型链继承 中的第三个问题)

3.组合式继承

原理

将原型链继承和构造函数继承这两种方式进行结合

代码演示

//父
//
function Father(x){
  this.x=x
}
//公有属性
Father.prototype.getX=function(){
    console.log('getX',this.x)
}
//
//子
//
function Son(x){
  this.y=y
  //2.call继承
  Father.call(this,x=100)
}
//
//1.原型链继承
//
Son.prototype=new Father(x=100)
//
Son.prototype.constructor=Son
//
Son.prototype.gety=function(){}
let s=new Son(y=200)

特点

1). 子类可以使用父类的私有属性和方法

2). 父类的私有属性和方法也会变成子类实例的私有属性和方法

3). 子类可以继承父类prototype上面的属性和方法

4). 子类实例的原型链上,或多一份父类的私有属性和方法(因为调用了两次父)

4.寄生式继承

原理

结合原型链继承和call继承的方法,同时自己创建一个对象,并且让这个对象的原型指向父类构造函数的prototype,实现寄生式继承

代码演示

//父
//
function Father(x){
  this.x=x
}
//公有属性
Father.prototype.getX=function(){
    console.log('getX',this.x)
}
//
//子
//
function Son(x){
  this.y=y
  //2.call继承
  Father.call(this,x=100)
}
//
//1.原型链继承
//
Son.prototype=Object.create(Father.prototype) //将父的原型给创建出来的新对象
//
Son.prototype.constructor=Son
//
Son.prototype.gety=function(){}
let s=new Son(y=200)

  Object.create()的实现

Object.create = function(obj){ 
//创建一个新的构造函数 
   function NewObj(){}   

   NewObj.prototype = obj; 

   return new NewObj()
}

特点

1). 最完美的js继承方案

2).父类私有的属性和方法,子类实例私有的属性和方法

3).父类公有的属性和方法,子类实例公有的属性和方法

4).子类实例修改公有的属性和方法不会影响父类的实例

运行机制

 


ES6的继承

出现的原因

1.当使用 寄生式继承 时,没办法将子的constructor重新指向子

2.使用 构造函数实现继承 时,没办法将父当做普通函数来执行

原理

通过extends实现继承

class 子类的构造函数 extends 父类的构造函数
Son.prototype.__proto__=Father.prototype

代码演示

// 父类
class Father{
    constructor(参数){
        this.x=x
    }
    getX(){}
}
//
//子类
class Son extends Father{
    constructor(参数){
        super()  //相当于es5中的 Father.call(this,传给父的参数),
        this.y=y
    }
    getY(){}
}
let s=new Son(y=200)

注意:
1.如果不写constructor,不会报错,继承会正常执行;浏览器会自动的帮我们去创建以下代码
    constructor(...args){
         super(...args)
      }
2.如果通过继承的方式写了constructor,那么必须使用super来继承父类的私有属性和方法,否则会报错; super 必须在子类this之前(即拓展自己的私有属性之前)调用,放到this之后会报错;

特点

  1. 父类的私有属性和方法,会成为子类的私有属性和方法

  2. 父类的公有属性变成子的公有属性

总上,es6中的继承,较为简单易懂,可以快速地解决我们的需求;以上就是我所了解的js中的继承.如有需有补充的地方,还请各位大佬指教!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值