JavaScript全解析-继承

news2024/11/19 8:36:37

继承

 

 

●要知道什么是继承
●要知道继承的方式有哪些
●每种的继承方式是如何实现的
什么是继承
●继承关系出现在构造函数和构造函数之间
●当构造函数A 的实例使用了 构造函数B 的属性和方法
●我们就说 构造函数A 继承自 构造函数B
○管 构造函数A 叫做子类
○管 构造函数B 叫做父类
●总结 :继承就是获取存在对象已有属性和方法的一种方式

function Person(name, age) {
      this.name = name
      this.age = age
    }

    Person.prototype.play = function () { console.log('玩游戏') }

    // 将来我创建的 Person 的实例, 就会出现两个属性一个方法
    const p = new Person('Jack', 18)
    console.log(p)

    function Student(classRoom) {
      this.classRoom = classRoom
    }

    // 将来我创建的 Student 的实例
    // 当我的 s 实例能使用 name 属性, age 属性 和 play 方法的时候
    // 我们就说 Student 构造函数继承自 Person 构造函数
    // Student 就是 子类
    // Person 就是 父类
    const s = new Student(2114)
    console.log(s)


复制代码

文章底部扫码,免费领取web前端资料大礼包!

继承的方式有哪些
原型继承
●核心: 让子类的原型指向父类的实例
●优点:
○父类构造函数体内的属性和原型上的方法都可以实现继承
●缺点:
○继承下来的属性不在自己身上, 在自己的原型上
○一个构造函数的实例, 需要在两个地方传递参数
○所有子类的实例, name 和 age 一模一样

<script>
    // 父类
    function Person(name, age) {
        this.name = name
        this.age = age
    }
    Person.prototype.play = function() {
        console.log('玩游戏')
    }
    // 子类
    function Student(classRoom) {
        this.classRoom = classRoom
    }
    // 实现继承
    const p = new Person('Jack', 18)
    Student.prototype = p
    //  此时 s 的 __proto__ 指向谁 ?
    //  指向所属构造函数的 prototype
    //  因为 Student.prototype 就是 就是 Person 的实例
    //  s 的 __proto__ 就是 Person 的实例
    const s = new Student(2114)
    console.log(s)
    // 当你访问 s 的 classRoom 成员的时候
    // 自己有直接使用
    console.log(s.classRoom)
    // 当你访问 s 的 name 成员的时候
    // 自己没有, 去到自己的 __proto__ 上查找
    // 因为自己的__proto__ 就是 Person 的实例
    // 其实就是去到 Person 的实例上查找
    console.log(s.name)
    // 当你访问 s 的 play 成员的时候
    // 自己没有, 去到自己的 __proto__ 上查找
    // 也就是去到 Person 的实例上查找, 发现还是没有
    // 就再去 __proto__ 上查找
    // 自己的 __proto__ 的 __proto__
    // Person 实例      的 __proto__
    // Person 实例 的 __proto__ 就是 Person.prototype
    s.play()
    const s2 = new Student(2115)
    console.log(s2)
</script>


复制代码

借用构造函数继承
●核心: 把父类构造函数当做普通函数调用, 并且改变其 this 指向
●优点:
○子类的所有继承下来的属性都在自己身上
○子类的所有参数在一个地方传递
○子类的所有实例都可以给继承下来的属性赋不一样的值
●缺点:
○父类的原型上的方法没有继承下来


  // 父类
    function Person(name, age) {
        this.name = name
        this.age = age
    }
    Person.prototype.play = function() {
        console.log('玩游戏')
    }
    // 子类
    function Student(classRoom, name, age) {
        this.classRoom = classRoom
        // 实现继承
        Person.call(this, name, age)
    }
    const s = new Student(2114, 'Jack', 18)
    console.log(s)
    const s2 = new Student(2115, 'Rose', 20)
    console.log(s2)


复制代码

组合继承
●核心: 把原型继承和借用构造函数继承放在一起使用
●优点:
○都能继承下来
○属性在自己身上, 每一个子类实例继承的属性值都可以不一样
●缺点:
○子类的原型上多了一套属性


<script>
    // 父类
    function Person(name, age) {
        this.name = name
        this.age = age
    }
    Person.prototype.play = function() {
        console.log('玩游戏')
    }
    // 子类
    function Student(classRoom, name, age) {
        this.classRoom = classRoom
        // 借用继承
        // 目的: 把属性继承在自己身上
        Person.call(this, name, age)
    }
    // 原型继承
    // 目的: 继承父类原型上的方法
    Student.prototype = new Person()
    // 创建子类的实例
    const s = new Student(2114, 'Rose', 20)
    console.log(s)
</script>


复制代码

ES6类继承
●类的继承是ES6中提出的一种继承方式
●这个继承有了语法的规定,必须要按照这样的方式来继承
●类的继承的实现: 两个步骤实现继承
○书写子类的时候, 加上 extends 关键字
■class 子类 extends 父类 {}
■目的: 继承父类原型上的方法
○在子类的 constructor 内书写 super()
■super(实参)
■目的: 继承父类的属性
●注意:
○必须要书写 super 和 extends
○在子类的 constructor 内 super 必须写在 this.xxx 的前面(最前面)
●父类可以是构造函数,但是子类不能的构造函数因为extends和super关键字就是给类设计的


<script>
    // 父类
    class Person {
        constructor(name, age) {
            this.name = name
            this.age = age
        }
        play() {
            console.log('玩游戏')
        }
    }
    // 父类
    // function Person(name, age) {
    //   this.name = name
    //   this.age = age
    // }
    // Person.prototype.play = function () { console.log('玩游戏') }
    // 子类
    class Student extends Person {
        constructor(classRoom, name, age) {
            super(name, age)
            this.classRoom = classRoom
        }
        study() {
            console.log('学习')
        }
    }
    const s = new Student(2114, 'Jack', 18)
    console.log(s)
    class Teacher extends Person {
        constructor(gender, name, age) {
            super(name, age)
            this.gender = gender
        }
    }
    const t = new Teacher('男', 'Jack', 20)
    console.log(t)
</script>


复制代码

文章底部扫码,免费领取web前端资料大礼包!

拷贝继承
●利用 for in 循环遍历对象
●把所有的内容复制一份放在子类的原型上


   // 书写 for in 循环的时候, 不光可以遍历到对象自己身上的属性, 也可以遍历到原型上的属性
    // 父类
    function Person(name, age) {
      this.name = name
      this.age = age
    }
    Person.prototype.sayHi = function () { console.log('hello world') }

    // 创建一个父类的实例
    // const p = new Person('Jack', 18)
    // console.log(p)
    // for (let k in p) {
    //   console.log(k)
    // }

    // 子类
    function Student(gender, ...arg) {
      this.gender = gender

      // 创建一个父类的实例
      const p = new Person(...arg)
      // 利用 for in 循环继承
      for (let k in p) {
        // 随着循环, k 分别是 name age 和 sayHi
        Student.prototype[k] = p[k]
      }
    }

    const s = new Student('男', 'Jack', 18)
    console.log(s)
    console.log(s.name)
    const s2 = new Student('女', 'Rose', 20)
    console.log(s2)
    console.log(s2.name)


复制代码

寄生式继承

   /*
      寄生式继承1

    */

    // 父类
    function Person(name) {
      this.name = name
    }
    Person.prototype.sayHi = function () { console.log('hello world') }

    // 子类
    //   构造函数内不要写 return
    function Student() {
      // 直接在子类里面 return 一个父类的实例
      const p = new Person('Jack')
      return p
    }

    // 创建一个子类的实例
    // 看似得到的是 Student 的实例, 但是其实得到的还是 Person 的实例
    const s = new Student()
    console.log(s)
    
    
    
       /*
      寄生式继承2 - 对寄生式继承1 的 改造
    */

    // 父类
    function Person(name) {
      this.name = name
    }
    Person.prototype.sayHi = function () { console.log('hello world') }

    // 子类
    //   构造函数内不要写 return
    function Student(gender) {
      this.gender = gender
    }

    // 寄生一下 父类的原型
    // Student的原型指向 Person的原型
    Student.prototype = Person.prototype

    // 创建一个子类的实例
    // Student 自己没有原型使用了, 直接使用 Person 的原型
    const s = new Student('男')
    console.log(s) 
    
    
    
        // 寄生式组合继承

    // 父类
    function Person(name, age) {
      this.name = name
      this.age = age
    }
    Person.prototype.sayHi = function () { console.log('hello world') }


    // 实现继承
    //   借助一个第三方构造函数
    function Third() {}
    //   第三方构造函数去继承 父类
    //   利用寄生继承的方式来实现
    // 第三方的 原型 指向 父类的原型
    Third.prototype = Person.prototype
    // 将来我使用第三方创建实例的时候
    const t = new Third()

    // 子类
    function Student(...arg) {
      // 利用 call 继承
      Person.call(this, ...arg)
    }
    // 子类去想办法继承第三方的内容
    //   利用原型继承去继承第三方内容
    //   子类的原型指向第三方的实例
    Student.prototype = new Third()
    const s = new Student('Jack', 18)
    console.log(s)


    // 利用了一个自执行函数
    // 自执行函数, 不需要名字的函数
    ;(function () {
      var a = 100
      console.log('你好 世界')
    })()


    // 子类
    function Student(gender, ...arg) {
      this.gender = gender

      Person.call(this, ...arg)
    }

    // 把 第三方内容 放在自执行函数内
    (function () {
      function Third() {}
      Third.prototype = Person.prototype
      Student.prototype = new Third()
    })()

    const s = new Student('男', 'Jack', 18)
    console.log(s)



复制代码

文章底部扫码,免费领取web前端资料大礼包!

冒充式继承


    /*
      冒充继承
        + 利用了一个浅拷贝 + 寄生继承
    */

    // 父类
    function Person(name, age) {
      this.name = name
      this.age = age
    }
    Person.prototype.sayHi = function () { console.log('hello world') }

    const p = new Person('Jack', 18)

    // 寄生继承
    function Student(gender) {
      this.gender = gender

      // 创建完毕实例以后, 拷贝一个父类的实例
      Object.assign(this, p)
    }
    Student.prototype = Person.prototype

    const s = new Student('男')


    console.log(s)


 

 如果上面的文章看着比较枯燥,点击下面的链接直接观看:

千锋教育JavaScript全套视频教程(10天学会Js,前端javascript入门必备)

 

 也可以扫码直接观看视频哦!绝对的干货满满,更多精彩视频B站搜索“千锋教育” 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/543190.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MATLAB算法实战应用案例精讲-【数模应用】生存曲线(补充篇)

目录 前言 几个相关概念 生存概率与死亡概率 生存率 生存曲线 事件、生存时间 中位生存时间 生存率的比较 生存数据 风险集 如何读懂KM曲线 应用案例 新药对患者总生存时间的影响-KM曲线 软件操作及结果解读 应用GraphPad Prism制作生存曲线 SPSS绘制生存曲线图 …

gRPC-go参数功能介绍1->WithBlock参数介绍

在gRPC-go框架中&#xff0c;当客户端使用 Dial() 方法连接到gRPC服务器时&#xff0c;可以使用 WithBlock() 选项来阻塞客户端&#xff0c;直到与服务器建立连接成功。 通常情况下&#xff0c;当客户端调用 Dial() 方法时&#xff0c;该方法会立即返回&#xff0c;并在后台异…

使用MinIO文件存储系统【完成图片上传保存】业务逻辑

目录 1&#xff1a;业务流程 2&#xff1a;接口实现 controller层 service层 1&#xff1a;业务流程 步骤一&#xff1a;前端进入上传图片的界面 步骤二&#xff1a;上传图片&#xff0c;请求到后端的媒资管理服务模块 步骤三&#xff1a;媒资管理服务将图片文件存储到m…

STM32---编写呼吸灯串口发送ON开LED,发送OFF关LED或者0X550X440XFF表示开灯,0X550X660XFF表示关灯

编写呼吸灯串口发送ON开LED&#xff0c;发送OFF关LED或者&#xff08;0X550X440XFF表示开灯&#xff0c;0X550X660XFF表示关灯&#xff09;注&#xff1a;包头 0X55 包尾&#xff1a;0XFF 数据&#xff1a;0X44表示开灯 0X66表示关灯 用到了重定向 //printf的重定向 int fpu…

使用SSD会提高游戏性能或FPS吗?

​“我在考虑要不要给电脑换个SSD&#xff0c;现在旧电脑上的HDD快满了&#xff0c;正好我也喜欢打游戏&#xff0c;听说换SSD可以提高电脑性能以及游戏FPS&#xff0c;这是真的吗&#xff1f;如果是真的&#xff0c;那我怎么样可以把旧硬盘上的数据迁移到新硬盘呢&#xff1f;…

【Web3.0大势所趋】下一代互联网的未来

前言 Web3.0 是一个越来越受到关注的话题&#xff0c;它被认为将会带来天翻地覆的变化。本文我们一起来谈谈 Web3.0 的概念、特点和优势&#xff0c;并探讨它为什么如此重要和具有革命性的。 文章目录 前言Web3.0是什么区块链技术智能合约总结 Web3.0是什么 Web3.0: 是下一代互…

达梦数据库的安装DM8

文章目录 一、达梦数据库的安装1、环境需求2、达梦的官方安装文档3、达梦数据库的安装包下载3.1、DM8的下载3.2、DM7的下载 4、开始操作4.1、使用xftp传dm8到虚拟机里4.2、下载依赖包4.3、拷贝dm8的iso文件到指定目录&#xff0c;并挂载4.4、创建DM安装用户和安装用户组并初始化…

提前熟知领英被限制被封因素,避免踩坑

领英在什么情况下容易被封 01.同一个人注册使用多个领英帐号。 02.多个人共同使用同一个领英帐号。 03.虚假资料注册领英账号&#xff0c;常见于注册领英账号的时候初始姓名随便填写或胡编乱造&#xff0c;注册时使用了网络虚拟的手机号码或邮箱等。 04.领英帐号的个人档案资料…

unity多线程Burst+Job System

Unity自己本身UnityEngine所使用的API是不能被多线程调用的&#xff0c;它没有向用户开放线程接口&#xff0c;所以Unity是不能使用多线程的&#xff0c;但是C#中可以使用多线程&#xff0c;Unity使用C#进行脚本编辑&#xff0c;故而Unity也可以通过C#来调用多线程。 JobSyste…

如何在新能源行业运用IPD?

新能源又称非常规能源&#xff0c;一般指在新技术基础上&#xff0c;可系统地开发利用的可再生能源。是指传统能源之外的各种能源形式&#xff0c;也是指刚开始开发利用或正在积极研究、有待推广的能源&#xff0c;如太阳能、地热能、风能、海洋能、生物质能和核聚变能等。目前…

HTTP与HTTPS的区别

1 HTTP与HTTPS有哪些区别 HTTP 是超文本传输协议&#xff0c;信息是明文传输&#xff0c;存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷&#xff0c;在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议&#xff0c;使得报文能够加密传输。HTTP 连接建立相对简单&#x…

你的私人编程老师,ChatGPT帮你快速掌握Python编程

ChatGPT为我们提供了一种全新的学习方式&#xff0c;让你可以更轻松&#xff0c;更快速地学习编程知识。 以下是ChatGPT帮助用户学习编程的优势&#xff1a; 推荐资源和课程ChatGPT可以根据您的编程经验和学习目标&#xff0c;推荐适合您的在线学习资源和课程。例如&#xff0c…

Go类型断言

在Go语言中类型断言的语法格式如下&#xff1a; value, ok : x.(T) 类型断言失败&#xff0c;不会发生panic。根据ok判断是否成功 或者 value: x.(T) 类型断言失败&#xff0c;会发生panic 其中&#xff0c;x 表示一个接口的类型&#xff0c;T 表示一个具体的类型&#xff08;也…

希望所有计算机专业同学都知道这些老师

C语言教程——翁凯老师、赫斌 翁恺老师是土生土长的浙大码农&#xff0c;从本科到博士都毕业于浙大计算机系&#xff0c;后来留校教书&#xff0c;一教就是20多年。 翁恺老师的c语言课程非常好&#xff0c;讲解特别有趣&#xff0c;很适合初学者学习。 郝斌老师的思路是以初学…

进口常用除氟树脂品牌

随着经济的发展&#xff0c;半导体、表面处理、采矿等行业产生了大量的高氟废水&#xff0c;由于高氟水对人体健康具有较大危害&#xff0c;含氟污水治理己经引起了广泛的关注。 多年以前&#xff0c;含氟废水的处理&#xff0c;一般下游污水处理厂通过合并多股废水&#xff0…

html监听界面被隐藏或显示

vue相比于小程序和uni-app 显然少了两个有点用的生命周期 onShow 应用被展示 onHide 应用被隐藏 但其实这个 要做其实也很简单 JavaScript中 有对应的visibilitychange事件可以监听 我们Html参考代码如下 <!DOCTYPE html> <html lang"en"> <head>…

在GB28181项目中,调用eXosip_register_send_register函数并且返回值为-2或者-3的含义是什么

一、eXosip_register_send_register返回-2的原因&#xff1a; 在GB28181项目中&#xff0c;调用eXosip_register_send_register函数并且返回值为-2通常表示注册发送失败。该返回值的含义是注册请求被拒绝&#xff0c;可能是由于身份验证失败或其他原因导致的。 以下是可能导致…

人车混合机器人实现身体平衡功能

1. 功能说明 在R035c样机上安装一个六轴陀螺仪传感器&#xff0c;本文示例将实现机器人身体平衡功能。当用手把机器人人形部分摆动到左侧时&#xff0c;人形部分会自动恢复到中间&#xff1b;当用手把机器人人形部分摆动到右侧时&#xff0c;人形部分也会自动恢复到中间。 ​ 2…

简历照片底色要求是什么?怎么修改证件照底色?

准备一份完美的简历是找到工作的关键之一。其中一个重要的组成部分是照片。照片可以让我们的简历更加生动活泼&#xff0c;同时也可以为面试官在面试时提供更好的印象。但是&#xff0c;如果在照片中使用了错误的背景色&#xff0c;那么简历可能会被忽略或被视为不专业。因此&a…

数据结构与算法——求二叉树叶子数量求二叉树高度

递归特性求树的高度流程图 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> //二叉树的节点结构体 struct BinaryNode {char ch;//显示的字母struct BinaryNode * lChild;//左孩子struct BinaryNode * rChil…