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 相关文章推荐
JavaScript 对象的属性和方法4种不同的类型
Mar 19 Javascript
关于jquery append() html时的小问题的解决方法
Dec 16 Javascript
jQuery插件jQuery-JSONP开发ajax调用使用注意事项
Nov 22 Javascript
关闭页面时window.location事件未执行的原因分析及解决方案
Sep 01 Javascript
小议JavaScript中Generator和Iterator的使用
Jul 29 Javascript
ANGULARJS中使用JQUERY分页控件
Sep 16 Javascript
在JavaScript中如何解决用execCommand(
Oct 19 Javascript
对存在JavaScript隐式类型转换的四种情况的总结(必看篇)
Aug 31 Javascript
解决vuejs 使用value in list 循环遍历数组出现警告的问题
Sep 26 Javascript
JS原型prototype和__proto__用法实例分析
Mar 14 Javascript
详解为什么Vue中不要用index作为key(diff算法)
Apr 04 Javascript
原生JavaScript创建不可变对象的方法简单示例
May 07 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使用递归方式列出当前目录下所有文件的方法
2015/06/02 PHP
PHP小程序支付功能完整版【基于thinkPHP】
2019/03/26 PHP
通过event对象的fromElement属性解决热区设置主实体的一个bug
2008/12/22 Javascript
判断iframe是否加载完成的完美方法
2010/01/07 Javascript
JavaScript DOM学习第八章 表单错误提示
2010/02/19 Javascript
jquery 操作表格实现代码(多种操作打包)
2011/03/20 Javascript
使用ImageMagick进行图片缩放、合成与裁剪(js+python)
2013/09/16 Javascript
JS二维数组的定义说明
2014/03/03 Javascript
jQuery实现鼠标划过展示大图的方法
2015/03/09 Javascript
基于jquery插件实现拖拽删除图片功能
2020/08/27 Javascript
微信小程序 for 循环详解
2016/10/09 Javascript
Angular.JS学习之依赖注入$injector详析
2016/10/20 Javascript
Bootstrap CSS组件之按钮下拉菜单
2016/12/17 Javascript
js实现简易垂直滚动条
2017/02/22 Javascript
JavaScript使用readAsDataURL读取图像文件
2017/05/10 Javascript
angular.js中解决跨域问题的三种方式
2017/07/12 Javascript
vue增删改查的简单操作
2017/07/15 Javascript
集合Bootstrap自定义confirm提示效果
2017/09/19 Javascript
JavaScript实现的反序列化json字符串操作示例
2018/07/18 Javascript
Vue项目中最新用到的一些实用小技巧
2018/11/06 Javascript
深入浅析ng-bootstrap 组件集中 tabset 组件的实现分析
2019/07/19 Javascript
解决layui批量传值到后台操作时出现传值为空的问题
2019/09/28 Javascript
vue使用showdown并实现代码区域高亮的示例代码
2019/10/17 Javascript
微信小程序wxs实现吸顶效果
2020/01/08 Javascript
[58:18]2018DOTA2亚洲邀请赛3月29日 小组赛B组 iG VS Mineski
2018/03/30 DOTA
Python编程中实现迭代器的一些技巧小结
2016/06/21 Python
Python生成器以及应用实例解析
2018/02/08 Python
详解Python 数据库的Connection、Cursor两大对象
2018/06/25 Python
Python 实现自动完成A4标签排版打印功能
2020/04/09 Python
Python调用C/C++的方法解析
2020/08/05 Python
给海归自荐信的建议
2013/12/13 职场文书
安全教育实施方案
2014/03/02 职场文书
普通员工辞职信范文
2015/05/12 职场文书
2015年教导处教学工作总结
2015/07/22 职场文书
html5 录制mp3音频支持采样率和比特率设置
2021/07/15 Javascript
Netflix《海贼王》真人版剧集多张片场照曝光
2022/04/04 日漫