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 相关文章推荐
json原理分析及实例介绍
Nov 29 Javascript
深入理解JavaScript编程中的同步与异步机制
Jun 24 Javascript
JavaScript判断表单中多选框checkbox选中个数的方法
Aug 17 Javascript
JavaScript中this的9种应用场景及三种复合应用场景
Sep 12 Javascript
jQuery实现模仿微博下拉滚动条加载数据效果
Dec 25 Javascript
jQuery实现两列等高并自适应高度
Dec 22 Javascript
从零学习node.js之mysql数据库的操作(五)
Feb 24 Javascript
JS实现css hover操作的方法示例
Apr 07 Javascript
全面解析Node.js 8 重要功能和修复
Jun 02 Javascript
vue-router+vuex addRoutes实现路由动态加载及菜单动态加载
Sep 28 Javascript
Vue发布订阅模式实现过程图解
Apr 30 Javascript
Element Alert警告的具体使用方法
Jul 27 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绘制在图片上的正余弦曲线
2013/06/08 PHP
php实现天干地支计算器示例
2014/03/14 PHP
php微信开发之自定义菜单完整流程
2016/10/08 PHP
PHP重置数组为连续数字索引的几种方式总结
2018/03/12 PHP
js cookies实现简单统计访问次数
2009/11/24 Javascript
js跨浏览器实现将字符串转化为xml对象的方法
2013/09/25 Javascript
基于jquery扩展漂亮的下拉框可以二次修改
2013/11/19 Javascript
textarea 控制输入字符字节数(示例代码)
2013/12/27 Javascript
Javascript 按位左移运算符使用介绍(
2014/02/04 Javascript
jQuery获取节点和子节点文本的方法
2014/07/22 Javascript
JavaScript获取Url里的参数
2014/12/18 Javascript
jQuery的观察者模式详解
2014/12/22 Javascript
学做Bootstrap的第一个页面
2016/05/15 HTML / CSS
JS中关于事件处理函数名后面是否带括号的问题
2016/11/16 Javascript
vue-hook-form使用详解
2017/04/07 Javascript
微信小程序 本地数据读取实例
2017/04/27 Javascript
Vue+ElementUI实现表单动态渲染、可视化配置的方法
2018/03/07 Javascript
小程序实现发表评论功能
2018/07/06 Javascript
JavaScript基础之this和箭头函数详析
2019/09/05 Javascript
微信小程序网络请求实现过程解析
2019/11/06 Javascript
微信小程序云开发获取文件夹下所有文件(推荐)
2019/11/14 Javascript
[51:43]OG vs LGD 2018国际邀请赛淘汰赛BO3 第五场 8.26
2018/08/30 DOTA
Python中使用插入排序算法的简单分析与代码示例
2016/05/04 Python
django 创建过滤器的实例详解
2017/08/14 Python
pandas 两列时间相减换算为秒的方法
2018/04/20 Python
Python requests发送post请求的一些疑点
2018/05/20 Python
浅谈Python 敏感词过滤的实现
2019/08/15 Python
解决django FileFIELD的编码问题
2020/03/30 Python
Python定时从Mysql提取数据存入Redis的实现
2020/05/03 Python
python线程池如何使用
2020/05/28 Python
详解Scrapy Redis入门实战
2020/11/18 Python
周生生珠宝香港官网:Chow Sang Sang(香港及海外配送)
2019/09/05 全球购物
中文专业毕业生自荐书范文
2014/01/04 职场文书
激励员工的口号
2014/06/16 职场文书
小学网上祭英烈活动总结
2014/07/05 职场文书
堂吉诃德读书笔记
2015/06/30 职场文书