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 相关文章推荐
更正确的asp冒泡排序
May 24 Javascript
JavaScript Date对象 日期获取函数
Dec 19 Javascript
JQuery中关于jquery.js与jquery.min.js的比较探讨
May 15 Javascript
javascript截取字符串(通过substring实现并支持中英文混合)
Jun 24 Javascript
使用jquery解析XML的方法
Sep 05 Javascript
JQuery使用index方法获取Jquery对象数组下标的方法
May 18 Javascript
jQuery实现MSN中文网滑动Tab菜单效果代码
Sep 09 Javascript
Node.js的Koa框架上手及MySQL操作指南
Jun 13 Javascript
浅谈addEventListener和attachEvent的区别
Jul 14 Javascript
JavaScript实现简单的树形菜单效果
Jun 23 Javascript
js截取字符串功能的实现方法
Sep 27 Javascript
vue element中axios下载文件(后端Python)
May 10 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 Notice: Undefined index 错误提示解决方法
2010/08/29 PHP
Admin generator, filters and I18n
2011/10/06 PHP
Smarty模板常见的简单应用分析
2016/11/15 PHP
使用ThinkPHP生成缩略图及显示
2017/04/27 PHP
PHP更安全的密码加密机制Bcrypt详解
2017/06/18 PHP
javascript 按键事件(兼容各浏览器)
2013/12/20 Javascript
JavaScript定义变量和变量优先级问题探讨
2014/10/11 Javascript
浅谈JavaScript 中有关时间对象的方法
2016/08/15 Javascript
jQuery常见的选择器及用法介绍
2016/12/20 Javascript
jQuery html表格排序插件tablesorter使用方法详解
2017/02/10 Javascript
Vue2组件tree实现无限级树形菜单
2017/03/29 Javascript
JS中type="button"和type="submit"的区别
2017/07/04 Javascript
JScript实现地址选择功能
2017/08/15 Javascript
javascript实现计算指定范围内的质数示例
2018/12/29 Javascript
Vue开发之封装上传文件组件与用法示例
2019/04/25 Javascript
Vue中this.$nextTick的作用及用法
2020/02/04 Javascript
nodejs中的异步编程知识点详解
2021/01/17 NodeJs
vue使用过滤器格式化日期
2021/01/20 Vue.js
[19:15]DK战队纪录片
2014/09/02 DOTA
[53:36]Liquid vs VP Supermajor决赛 BO 第三场 6.10
2018/07/05 DOTA
由Python编写的MySQL管理工具代码实例
2019/04/09 Python
详解Python3之数据指纹MD5校验与对比
2019/06/11 Python
django实现支付宝支付实例讲解
2019/10/17 Python
使用python3 实现插入数据到mysql
2020/03/02 Python
python爬虫开发之使用python爬虫库requests,urllib与今日头条搜索功能爬取搜索内容实例
2020/03/10 Python
python线程里哪种模块比较适合
2020/08/02 Python
美国男士西装打折店:Jos. A. Bank
2017/11/13 全球购物
即将毕业大学生自荐信
2014/01/24 职场文书
五年级英语教学反思
2014/01/31 职场文书
个人授权委托书范本
2014/04/03 职场文书
安康杯竞赛活动总结
2014/05/05 职场文书
三严三实对照检查材料范文
2014/09/23 职场文书
初三语文教学计划
2015/01/22 职场文书
高考作弊检讨书1500字
2015/02/16 职场文书
Canvas三种动态画圆实现方法说明(小结)
2021/04/16 Javascript
html中相对位置与绝对位置的具体使用
2022/05/15 HTML / CSS