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 相关文章推荐
Div自动滚动到末尾的代码
Oct 26 Javascript
事件模型在各浏览器中存在差异
Oct 20 Javascript
JavaScript学习笔记记录我的旅程
May 23 Javascript
分享一个我自己写的ToolTip提示插件(附源码)
Jan 20 Javascript
httpclient模拟登陆具体实现(使用js设置cookie)
Dec 11 Javascript
js获取当前路径的简单示例代码
Jan 08 Javascript
JavaScript获取短信验证码(周期性)
Dec 29 Javascript
详解Node.js项目APM监控之New Relic
May 12 Javascript
Cropper.js 实现裁剪图片并上传(PC端)
Aug 20 Javascript
详解使用webpack打包编写一个vue-toast插件
Nov 08 Javascript
AjaxUpLoad.js实现文件上传功能
Mar 02 Javascript
一文带你理解vue创建一个后台管理系统流程(Vue+Element)
May 18 Vue.js
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
echo(),print(),print_r()之间的区别?
2006/11/19 PHP
一些 PHP 管理系统程序中的后门
2009/08/05 PHP
PHP中函数rand和mt_rand的区别比较
2012/12/26 PHP
浅析PHP文件下载原理
2014/12/25 PHP
Laravel 5框架学习之向视图传送数据
2015/04/08 PHP
CSS中简写属性要注意TRouBLe的顺序问题(避免踩坑)
2021/03/09 HTML / CSS
自制轻量级仿jQuery.boxy对话框插件代码
2010/10/26 Javascript
js中定义一个变量并判断其是否为空的方法
2014/05/13 Javascript
浅析JavaScript事件和方法
2015/02/28 Javascript
JS实现图片高亮展示效果实例
2015/11/24 Javascript
js自定义select下拉框美化特效
2016/05/12 Javascript
原生js仿jquery animate动画效果
2016/07/13 Javascript
JavaScript 对象详细整理总结
2016/09/29 Javascript
利用JS实现文字的聚合动画效果
2017/01/22 Javascript
js获取地址栏参数的两种方法
2017/06/27 Javascript
前端MVVM框架解析之双向绑定
2018/01/24 Javascript
微信小程序自定义组件封装及父子间组件传值的方法
2018/08/28 Javascript
理理Vue细节(推荐)
2019/04/16 Javascript
JavaScript随机数的组合问题案例分析
2020/05/16 Javascript
python监控网卡流量并使用graphite绘图的示例
2014/04/27 Python
Python的Flask框架标配模板引擎Jinja2的使用教程
2016/07/12 Python
Python 实现数据库更新脚本的生成方法
2017/07/09 Python
Python cookbook(数据结构与算法)在字典中将键映射到多个值上的方法
2018/02/18 Python
python中csv文件的若干读写方法小结
2018/07/04 Python
查看Python依赖包及其版本号信息的方法
2019/08/13 Python
Django调用百度AI接口实现人脸注册登录代码实例
2020/04/23 Python
k-means 聚类算法与Python实现代码
2020/06/01 Python
HTML5中FileReader接口使用方法实例详解
2017/08/26 HTML / CSS
html5 input属性使用示例
2013/06/28 HTML / CSS
专科毕业生自我鉴定
2013/12/01 职场文书
写自荐信的注意事项
2014/03/09 职场文书
贷款担保申请书
2014/05/20 职场文书
优秀研究生主要事迹
2014/06/03 职场文书
迎国庆演讲稿
2014/09/05 职场文书
师德师风个人整改措施
2014/10/27 职场文书
反邪教警示教育活动总结
2015/05/09 职场文书