JS继承最简单的理解方式


Posted in Javascript onMarch 31, 2021

我们可以简单的分为以下几种继承方式

  1. 原型链继承
  2. 构造函数继承
  3. 组合继承
  4. 寄生组合继承/加强版寄生组合继承
  5. 类继承

以下 A代表父级 B代表子级

我们先看原型链继承
先上代码

function A(name,age){
              this.name = name;
              this.arr = [];
              this.age = age;
              this.sing = function(){
                  return  '我会唱歌、我会跳舞。'
              }
          }
          function B(run){
              this.run = run
          }
          B.prototype = new A('zjq',18)
          console.log(new B()._proto_ === A.construct)
          let a = new B('123')
          let b = new B('456')
          a.arr.push('1')
          console.log(b.arr)  //['1']

B已经完全的集成到了A的属性和方法,但是有一个缺点就是当我们实例化两个B的时候,给第一个arr添加item,第二个实例化对象也会跟着变化。a和b的arr都新添了一个item。方法变成了共享,不是实例所私有的。(引用类型)

构造函数继承
上代码

function A(name,age){
              this.name = name;
              this.age = age;
              this.arr =[];
              this.sing = function(){
                  return  '我会唱歌、我会跳舞。'
              }
          }
          A.prototype.zjq = function(){
            return 'run'
        }
          function B(run){
              this.run = run
              A.call(this,'zjq',this.run) //父级的属性和方法称为子级的私有属性和方法  子级可以向父级传参
          }
          let Bobj = new B('runing')
          console.log(Bobj)
          console.log(Bobj.sing())
          let a = new B('123')
          let b = new B('456')
          a.arr.push('1')
          console.log(b.arr)  //[]

构造函数继承虽然可以使用A中的方法和属性,但是不是继承的关系过来的,它的_proto_上没有A的任何信息,它将A的属性和方法变成了自己的属性和方法,但是原型链上的方法(zjq方法并没有)是无法继承到的。创建子类实例,可以向父类构造函数传参数。解决了方法变成了共享的问题,变成了实例所私有的。

组合继承
上代码

function A(name, age) {
            this.name = name;
            this.age = age;
            this.arr=[]
        }
        A.prototype.sing = function () {
            return '我会唱歌、我会跳舞。' + this.name + this.age
        }
        function B(run) {
            this.run = run
            A.call(this, 'zjq', this.run) //父级的属性和方法称为子级的私有属性和方法  子级可以向父级传参
        }
        B.prototype = new A()
        let brr = new B('参数')
        let a = new B('123')
        let b = new B('456')
        a.arr.push('1')
        console.log(b.arr)  //[]
        console.log(brr)
        console.log(brr.sing())
        console.log(brr.age)

结合原型链继承和借用构造函数继承的优点 ,继承了A的属性和方法也可以向A传递自己的参数。解决了方法变成了共享的问题,变成了实例所私有的,但是A构造函数被调用了两次。

寄生组合继承
上代码

function A(name, age) {
            this.name = name;
            this.age = age;
            this.arr = []
        }
        A.prototype.sing = function () {
            return '我会唱歌、我会跳舞。' + this.name + this.age
        }
        function B(run) {
            this.run = run
            A.call(this, 'zjq', this.run)
        }
        B.prototype = A.prototype
        // let b= new B('123')
        // console.log(b)
        B.prototype.sing = function () {
            return 'xxx'
        }
        let a = new B('123')
        let b = new B('456')
        a.arr.push('1')
        console.log(b.arr)  //[]
        console.log(new A().sing())  //变成了xxx  而不是 return '我会唱歌、我会跳舞。' + this.name + this.age

解决了方法变成了共享的问题,变成了实例所私有的,但是又有一个突出的问题,B可以改变原型链上的东西,A和B共享了原型链。

加强版寄生组合继承

function A(name, age) {
            this.name = name;
            this.age = age;
        }
           A.prototype.sing = function () {
            return '我会唱歌、我会跳舞。' + this.name + this.age
        }
        function B(run) {
            this.run = run
            A.call(this, 'zjq', this.run) 
        }
        function f(){}
        f.prototype = A.prototype
        B.prototype = new f()
        let b= new B('123')
        console.log(b)
        B.prototype.sing = function(){
            return 'xxx'
        }
        console.log(new A().sing()) //return '我会唱歌、我会跳舞。' + this.name + this.age

解决了共享原型链的问题。 完美收官。

类继承
上代码

class A {//父级构造函数
            constructor(name) {
                this.name = name;
            }
            sing() {
                return this.name + 'xxx'
            }
        }

        class B extends A { //子级继承父级
            constructor(name,age) {
                super(name)  调用实现父类的构造函数  并传递参数
                this.age = age
            }
        }
        let b = new B(12333,222) //实例化子级
        console.log(b)
        console.log(b.sing()) //return this.name + 'xxx'

 

Javascript 相关文章推荐
不同的jQuery API来处理不同的浏览器事件
Dec 09 Javascript
jquery基础教程之deferred对象使用方法
Jan 22 Javascript
jQuery内部原理和实现方式浅析
Feb 03 Javascript
javascript中基本类型和引用类型的区别分析
May 12 Javascript
详解handlebars+require基本使用方法
Dec 21 Javascript
简单的渐变轮播插件
Jan 12 Javascript
vue-cli+webpack记事本项目创建
Apr 01 Javascript
浅谈Vue 数据响应式原理
May 07 Javascript
vscode中eslint插件的配置(prettier配置无效)
Sep 10 Javascript
vue项目实现图片上传功能
Dec 23 Javascript
微信小程序scroll-view的滚动条设置实现
Mar 02 Javascript
微信小程序实现canvas分享朋友圈海报
Jun 21 Javascript
javaScript Array api梳理
Mar 31 #Javascript
抖音短视频(douyin)去水印工具的实现代码
Nest.js参数校验和自定义返回数据格式详解
Mar 29 #Javascript
Angular CLI发布路径的配置项浅析
Mar 29 #Javascript
vue中data改变后让视图同步更新的方法
vue3如何优雅的实现移动端登录注册模块
开发一个封装iframe的vue组件
You might like
PHP实现的线索二叉树及二叉树遍历方法详解
2016/04/25 PHP
理解Javascript_03_javascript全局观
2010/10/11 Javascript
javascript Window及document对象详细整理
2011/01/12 Javascript
动态加载js和css(外部文件)
2013/04/17 Javascript
将HTML格式的String转化为HTMLElement的实现方法
2014/08/07 Javascript
jQuery与getJson结合的用法实例
2015/08/07 Javascript
jQuery easyUI datagrid 增加求和统计行的实现代码
2016/06/01 Javascript
AngularGauge 属性解析详解
2016/09/06 Javascript
jQuery 的 ready()的纯js替代方法
2016/11/20 Javascript
vue2.0 与 bootstrap datetimepicker的结合使用实例
2017/05/22 Javascript
使用watch监听路由变化和watch监听对象的实例
2018/02/24 Javascript
angular2组件中定时刷新并清除定时器的实例讲解
2018/08/31 Javascript
vue按需加载实例详解
2019/09/06 Javascript
JavaScript实现京东放大镜效果
2019/12/03 Javascript
Python中type的构造函数参数含义说明
2015/06/21 Python
Python数组遍历的简单实现方法小结
2016/04/27 Python
Python 实现文件的全备份和差异备份详解
2016/12/27 Python
Python框架Flask的基本数据库操作方法分析
2018/07/13 Python
Python中的枚举类型示例介绍
2019/01/09 Python
利用Python半自动化生成Nessus报告的方法
2019/03/19 Python
如何利用Python动态模拟太阳系运转
2020/09/04 Python
HTML5 Canvas实现放大镜效果示例
2020/03/25 HTML / CSS
与世界上最好的跑步专业品牌合作:Fleet Feet
2019/03/22 全球购物
英国比较机场停车场网站:Airport Parking Essentials
2019/12/01 全球购物
EJB2和EJB3在架构上的不同点
2014/09/29 面试题
计算机专业自我鉴定
2013/10/15 职场文书
大学生职业生涯规划书范文
2014/01/14 职场文书
小学生新学期寄语
2014/01/19 职场文书
运动会广播稿400字
2014/01/25 职场文书
楼面经理岗位职责范本
2014/02/18 职场文书
投标承诺书范本
2014/03/27 职场文书
篮球比赛拉拉队口号
2014/06/10 职场文书
防暑降温通知书
2015/04/27 职场文书
横空出世观后感
2015/06/09 职场文书
2015年城管执法工作总结
2015/07/23 职场文书
公文格式,规则明细(新手收藏)
2019/07/23 职场文书