【学习笔记65】JavaScript的继承

news2024/11/26 17:47:57

一、认识继承

        function Person(name) {
            this.name = name
        }
        Person.prototype.sayName = () => {
            console.log('name')
        }

        function Stu(age) {
            this.age = age
        }
    
        const s = new Stu(18)

        console.log(s)  // {age: 18}

说明: 

  • 想让s这个对象内部有一个name属性, 并且可以使用 sayName 这个方法
  • 可以通过继承的方式让Stu这个类, 继承上Person这个类内部的属性与原型上的方法

 二、原型继承

  • 核心:  就子类的原型指向父类的实例化对象
  • 优点:  实现了继承
  •  缺点: 继承了属性, 但是不在自己身上,失去了自己的原型
        // 1. Person父类
        function Person(name) {
            this.name = name
        }
        Person.prototype.sayName = () => {
            console.log('name')
        }

        // 2. Person子类
        function Stu(age) {
            this.age = age
        }
        Stu.prototype.abc = () => {
            console.log(123)
        }
        // 原型的继承
        Stu.prototype = new Person('QF001')
        Stu.prototype.abc2 = () => {
            console.log(456)
        }
        
        const s = new Stu(18)

        // 需求:使用Person内部的name和sayName 方法
        console.log(s)

  • 利用自定义原型的方式去继承,当Stu这个类继承了Person这个类的时候,我们把Person叫做Stu的父类,把Stu叫做Person的子类

1、原型继承的原理

  1. 先在对象内部查找name属性, 然后发现对象内部没有这个属性
  2. 再去对象内部的 __proto__ 上查找, 对象的__proto__ 指向了自己构造函数的原型,也就是指向了 Stu.prototype
  3. 因为我们手动修改了 Stu.prototype, 给他赋值为了 Person 构造函数的实例化对象
  4.  也就是说我们 Stu.prototype就指向了 Person的实例化对象
  5. Person的实例化对象内部有一个属性叫做name, 此时找到并返回

2、原型继承的运用

        function Person(name) {
            this.name = name
        }
        Person.prototype.sayName = () => {
            console.log('name')
        }

        // 2. Person子类
        function Stu(age) {
            this.age = age
        }
        Stu.prototype.abc = () => {
            console.log(123)
        }
        // 原型的继承
        Stu.prototype = new Person('QF001')
        Stu.prototype.abc2 = () => {
            console.log(456)
        }
        const s = new Stu(18)

        console.log(s)
        console.log(s.age)
        console.log(s.name)
        s.sayName()

三、借用构造函数继承

  • 核心: 借用 call 方法修改 父类构造函数内部的 this 指向
  • 优点: 将属性继承在自己身上,保留了自己的原型
  • 缺点: 只能继承父类的属性, 不能继承父类原型上的方法
        // 父类
        function Person(name) {
            this.abc = name;
            this.name = name;
        }
        Person.prototype.sayName = () => {
            console.log('name');
        }
        
        // Person的自类
        function Stu(age) {
            this.age = age;
            // .call 改变Stu的this指向父类
            Person.call(this, 'QF002');
        }

        const s = new Stu(18);
        console.log(s)

 1、原理

1. 通过new关键字调用Stu这个构造函数

2. new 关键会在这个函数内部创建一个空对象, 并且会把这个函数内部的this指定刚才创建的空对象

3. 我们现在开始正常执行函数代码

         给这个对象添加一个age属性, 并且给他赋值为参数age      参数 age === 18

         调用Perosn 这个函数, 并通过call方法改变这个函数内部的 this 指向,   this指向了刚才 new 关键字创建的对象

4. Person 函数开始执行

        给这个对象 添加一个abc的属性, 并赋值为参数name          参数 name === 'QF002'

        给这个对象 添加一个name的属性, 并赋值为参数name       参数 name === 'QF002'

5. 现在函数执行完毕, 然后new关键字,会将刚才创建的对象return

6. 将这个对象保存在了变量s

7. 通过上述流程, 我们认为 这个对象中应该是 {age:18, abc: 'QF002', name: 'QF002'}

 2、运用

        function Person(name) {
            this.abc = name;
            this.name = name;
        }
        Person.prototype.sayName = () => {
            console.log('name');
        }

        function Stu(age) {
            this.age = age;
            Person.call(this, 'QF002');
        }
        const s = new Stu(18);

        // 需求:使用Person内部的name和sayName 方法
        console.log(s);
        console.log(s.age);
        console.log(s.abc);
        console.log(s.name);
        s.sayName()   //报错:只能继承父类的属性, 不能继承父类原型上的方法

四、组合继承

组合继承

        1. 利用原型继承,继承到父类的原型上的方法

        2. 利用借用继承,继承到父类的构造函数内部的属性

 好处:

        1. 能继承到属性, 并且是在自己对象内部(自己身上)

        2. 能够继承到父类原型上的方法

 缺点: 在原型上,有一套多余的属性

        function Person(name) {
            this.abc = name;
            this.name = name;
        }
        Person.prototype.sayName = () => {
            console.log('hello');
        }
        function Stu(age) {
            this.age = age;

            // 2. 利用借用继承, 继承到父类的构造函数内部的属性
            Person.call(this, 'QF001');
        }

        // 1. 利用原型继承, 继承到父类的原型上的方法
        Stu.prototype = new Person();
        const s = new Stu(18);

        console.log(s);
        console.log(s.name);
        s.sayName();

  • 查找对象内部属性的时候, 会先在对象内部查找, 找到直接使用, 并停止查找

五、拷贝继承

 核心:

  • 通过for in遍历父类实例化对象上的所有属性, 拷贝到子类上,
  • 它能够遍历对象内部的属性, 以及原型
        function Person(name) {
            this.name = name;
        }
        Person.prototype.sayName = () => {
            console.log('name');
        }

        function Stu(age) {
            this.age = age;
            const p = new Person('QF001');

            for (let key in p) {
                Stu.prototype[key] = p[key];
            }
        }
        Stu.prototype.abc = () => {
            console.log(123);
        }

        const s = new Stu(18);
        console.log(s);

运用

        function Person(name) {
            this.name = name;
        }
        Person.prototype.sayName = () => {
            console.log('name');
        }

        function Stu(age) {
            this.age = age;
            const p = new Person('QF001');

            for (let key in p) {
                Stu.prototype[key] = p[key];
            }
        }
        Stu.prototype.abc = () => {
            console.log(123);
        }
        const s = new Stu(18);

        // // 需求:使Person内部的name何sayName方法
        console.log(s);
        console.log(s.age);
        console.log(s.name);
        s.abc();
        s.sayName();

六、ES6 类的继承

ES6 类的继承

        1. 语法: class 子类类名 extends 父类类名

        2. 在书写子类,constructor需要在内部书写super()

注意:

        1. 两个写法必须同时存在, 才能完成继承

        2. super() 必须在constructor 在开始位置

类的继承, 除了能够继承 class 类, 还能够继承 ES5 的构造函数

        function Person (name) {
            this.name = name;
        }
        Person.prototype.sayName = function () {
            console.log('name');
        }

        class Stu extends Person {
            constructor(age) {
                super('QF001');
                this.age = age;
            }
        }

        const s = new Stu(18);
        console.log(s);
        console.log(s.age);
        console.log(s.name);
        s.sayName();

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

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

相关文章

双功能连接试剂:Alkyne hydrazide,炔烃-酰肼 主要特点进行分享

Alkyne hydrazide物理参数: CAS号:N/A |英文名:Alkyne hydrazide | 中文名:炔烃-酰肼 货号:X-CL-1132 分子式:C6H11ClN2O 分子量:162.62 纯度:95% 外形:淡黄色或白…

企业级的商用远程控制软件有哪些

现在远程控制软件,可选性还是比较大的。针对个人用户市场,也有不少免费软件。 企业用户的需求和个人用户的需求,差别较大。个人用户市场,主要诉求是免费、好用。企业用户,主要关注安全、管理功能、性能、价格等因素。…

为什么建议MySQL在2000W条左右记录分表

为什么建议MySQL在2000W条左右记录分表?这个数量问题并不是绝对的,这是一个相对的数量。在回答这个问题前我们应该先了解MySQL底层是用的什么数据结构来进行数据存储的。 MySQL底层采用的B树进行的数据存储 InnoDB存储引擎最小储存单元是页,…

【Java面试】异常常见面试题

文章目录1. Error 和 Exception 区别是什么?运行时异常和一般异常(受检异常)区别是什么?JVM 是如何处理异常的?throw 和 throws 的区别是什么?final、finally、finalize 有什么区别?NoClassDefFoundError 和 ClassNotF…

OpenMP 快速入门

学习《高性能计算:现代系统与应用实践》(Thomas Sterling,Matthew Anderson,Maciej Brodowicz)第 7 章 OpenMP 的基础 OpenMP OpenMP 是一个 API C、C、Fortran OpenMP 是共享内存的多线程编程模型 共享内存 默认所有…

22年11月-自研-面试题

目录背景题目Activiti回退功能条件分支功能,并行网关、包含网关有没有用到流程流转中,需知会其他人,这些人需同意/做处理(有点流程的感觉),最后所有的意见都要汇总。你的实现思路Redis哪些数据结构&#xf…

STM32实战总结:HAL之低功耗

低功耗的含义不必过多解释,一听就能懂。 低功耗对电池供电产品尤其重要。 STM32的有三种低功耗模式,即睡眠模式、停止模式和待机模式。 在我的印象中,停止不就是关机吗?但并不是。 在系统或电源复位以后,微控制器处于运…

基于最小二乘插值(Least-Squares Interpolation)图像超分辨率重构算法研究-附Matlab代码

⭕⭕ 目 录 ⭕⭕✳️ 一、引言✳️ 二、最小二乘图像插值理论与Matlab处理✳️ 三、基于最小二乘插值超分辨重构实验验证✳️ 四、参考文献✳️ 五、Matlab程序获取与验证✳️ 一、引言 图像超分辨率重构技术起源于上世纪60年代Harris和Goodman构造的单帧图像重构方法&#xf…

AutoCAD Electrical 2022—元件的绘制

原理图——图标菜单 选择要插入的元件; 根据实际情况,选择垂直放置还是水平放置,比例大小; 选择一个三极断路器,垂直放置; 点击确定后,点击一根导线,选择断路器另外两个符号是的方向…

相控阵天线(十一):阵列天线有源驻波分析

目录简介有源驻波概念和计算公式平面阵列天线的有源驻波平面阵列有源驻波计算公式平面阵列有源驻波仿真示例不同耦合系数/隔离度的有源驻波分析简介 有源相控阵最大的特点是每一个收发天线后均连接一个独立的T/R组件,每一个T/R组件相当于一个常规雷达的高频前端&am…

【信息检索与数据挖掘期末笔记】(二) IR Evaluation

文章目录测试集无序检索结果集合的评价Precision & RecallAccuarcy?F值有序检索结果评价方法二值相关(相关/不相关)PrecisionK(PK)Mean Average Precision(MAP)Mean Reciprocal Rank多级相关CG&#x…

LeetCode542. 01 矩阵(C++中等题)

题目 给定一个由 0 和 1 组成的矩阵 mat ,请输出一个大小相同的矩阵,其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。 两个相邻元素间的距离为 1 。 示例 1: 输入:mat [[0,0,0],[0,1,0],[0,0,0]] 输出:[[…

(三) 共享模型之管程【共享带来的问题】

一、共享带来的问题 1. 临界区 (1)一个程序运行多个线程本身是没有问题的 (2)问题出在多个线程访问共享资源 1️⃣多个线程读共享资源其实也没有问题 2️⃣在多个线程对共享资源读写操作时发送指令交错,就会出现问题 …

git@github.com: Permission denied (publickey).

本地虚拟机ubuntu上安装git,想从github上拉取项目到ubuntu上的过程。 1、在ubuntu上安装git 更新apt指令 sudo apt update 安装git sudo apt install git 查看安装git版本 git --version 2、ssh认证 首先已经安装了ssh指令 先执行 ssh -T gitgithub.com 执行之…

3.11 怎么增加小红书评论区的互动?【玩赚小红书】

今天就为大家总结了一下,关于小红书粉丝互动的一些小技巧,来供大家参考。 ​ ​ 一、 固好“真爱粉” 经常会在笔记下面评论、点赞、浏览笔记内容的粉丝,也就是所谓的“真爱粉”、“铁粉”,我们就需要用心维护这一部分粉丝。 ​…

虹科分享|硬件加密U盘|居家办公的网络安全:远程员工可以采取的步骤

新冠肺炎的流行迫使数以百万计的人在家工作,而当时他们对这一概念知之甚少,甚至完全没有经验。虽然许多员工已经重返办公室,但最近的一项研究发现,72%的受访者希望每周至少有两天在家工作,32%的人表示他们希望永久在家…

全波形反演的深度学习方法: 第 4 章 基于正演的 FWI (草稿)

本章论述经典的 FWI, 它基于正演方法. 本贴仅供内部培训. 4.1 FWI 问题 图 4.1 FWI 的输入与输出 [1].图 4.2 FWI 的数学式子.正演问题是建立从速度模型到地震数据的映射. 一般认为是单解的, 即一个速度模型只能生成一个地震数据 (如果不考虑噪声).反演问题是建立从地震数据到…

【题解】E. Sending a Sequence Over the Network(1741)

链接:https://codeforces.com/problemset/problem/1741/E 题目大意 给出一个数组,判断它是否是合法的,如果合法则输出YES,不合法则输出NO。 合法规则:一段序列中,这个序列的第一个或者最后一个的数值&…

岩藻多糖-聚乙二醇-胆固醇Cholesterol-PEG-FucoidanFucoidan-Cholesterol 岩藻多糖-胆固醇

岩藻多糖-聚乙二醇-胆固醇Cholesterol-PEG-FucoidanFucoidan-Cholesterol 岩藻多糖-胆固醇 中文名称:岩藻多糖-胆固醇 英文名称:Fucoidan-Cholesterol 别称:胆固醇修饰岩藻多糖,胆固醇-岩藻多糖 外观:固体或粘性液体&#xff…

终于有人将TWI(串行通讯接口)给讲通了!

目录 TWI的特性 数据传输格式 时钟同步 数据仲裁 功能描述 总线接口单元 频率生成单元 地址匹配单元 控制单元 传输模式 主机发送模式 主机接收模式 从机发送模式 从机接收模式 TWI的特性 两线模式,简单快捷;支持主机模式和从机模式&#xff…