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 相关文章推荐
一个无限级XML绑定跨框架菜单(For IE)
Jan 27 Javascript
url 特殊字符 传递参数解决方法
Jan 01 Javascript
js简单的弹出框有关闭按钮
May 05 Javascript
jQuery的观察者模式详解
Dec 22 Javascript
javascript实现复选框选中属性
Mar 25 Javascript
JavaScript生成.xls文件的代码
Dec 22 Javascript
Angularjs中数据绑定的实例详解
Aug 25 Javascript
JS实现简易换图时钟功能分析
Jan 04 Javascript
vue 实现剪裁图片并上传服务器功能
Mar 01 Javascript
JavaScript插入排序算法原理与实现方法示例
Aug 06 Javascript
javascript 函数的暂停和恢复实例详解
Apr 25 Javascript
解决vscode进行vue格式化,会自动补分号和双引号的问题
Oct 26 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
CodeIgniter生成网站sitemap地图的方法
2013/11/13 PHP
php获得网站访问统计信息类Compete API用法实例
2015/04/02 PHP
php实现比较两个文件夹异同的方法
2015/06/18 PHP
PHP记录页面停留时间的方法
2016/03/30 PHP
PHPExcel在linux环境下导出报500错误的解决方法
2017/01/26 PHP
laravel框架关于搜索功能的实现
2018/03/15 PHP
PHP7 foreach() 函数修改
2021/03/09 PHP
firefox 和 ie 事件处理的细节,研究,再研究 书写同时兼容ie和ff的事件处理代码
2007/04/12 Javascript
Webkit的跨域安全问题说明
2011/09/13 Javascript
使用JS读秒使用示例
2013/09/21 Javascript
jquery 图片缩放拖动的简单实例
2014/01/08 Javascript
跟我学Node.js(四)---Node.js的模块载入方式与机制
2014/06/04 Javascript
JavaScript中的6种运算符总结
2014/10/16 Javascript
原生JavaScript实现滚动条效果
2020/03/24 Javascript
js去字符串前后空格的实现方法
2016/02/26 Javascript
Javascript 实现计算器时间功能详解及实例(二)
2017/01/08 Javascript
vue富文本框(插入文本、图片、视频)的使用及问题小结
2018/08/17 Javascript
微信小程序中的列表切换功能实例代码详解
2020/06/09 Javascript
Python的Django框架中URLconf相关的一些技巧整理
2015/07/18 Python
PyCharm使用教程之搭建Python开发环境
2016/06/07 Python
Django中间件实现拦截器的方法
2018/06/01 Python
python 通过 socket 发送文件的实例代码
2018/08/14 Python
Django中的静态文件管理过程解析
2019/08/01 Python
Jupyter notebook如何实现指定浏览器打开
2020/05/13 Python
python 制作磁力搜索工具
2021/03/04 Python
CSS3径向渐变之大鱼吃小鱼之孤单的大鱼
2016/04/26 HTML / CSS
css3实现小箭头各种图形效果
2020/07/08 HTML / CSS
努比亚手机官网:nubia
2016/10/06 全球购物
求两个数的乘积和商数,该作用由宏定义来实现
2013/03/13 面试题
仓库保管员岗位职责
2013/12/20 职场文书
工业学校毕业生自荐信范文
2014/01/03 职场文书
索桥的故事教学反思
2014/02/06 职场文书
建筑安全员岗位职责
2014/03/13 职场文书
村党支部书记四风问题个人对照检查材料思想汇报
2014/10/06 职场文书
安全生产工作汇报材料
2014/10/28 职场文书
学校少先队工作总结
2015/08/12 职场文书