ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JS中的继承

2021-10-01 22:03:34  阅读:141  来源: 互联网

标签:父类 JS 继承 子类 Son prototype 属性


所谓的继承,按我们所认识的就是儿子继承父亲的产业之类的;在我们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中的继承.如有需有补充的地方,还请各位大佬指教!

标签:父类,JS,继承,子类,Son,prototype,属性
来源: https://blog.csdn.net/lf811/article/details/120581085

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有