JS实现继承的几种方式

2023-05-16

JS继承的实现方式 堪称最全最详细

前沿看js继承这块时我看的几个教程都是说的很简单或者是没有说全就自行百度看了好多总结了下有:
1.构造函数继承 2.原型链继承 3.组合继承 4.class继承 5.实例继承 6 拷贝继承 7.寄生组合继承
下面我们就按照顺序来实现

实现继承前我们先构建一个父类代码如下:

function Animal (name) {
  this.name = name || 'Animal';
  this.sleep = function(){
    console.log(this.name + '正在睡觉!');
  }
}
Animal.prototype.eat = function(food) {  // 原型方法
  console.log(this.name + '正在吃:' + food);
};

instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
propotype的:使你有能力向对象添加属性和方法
new Animal()和Object.create(Animal.prototype)的区别:Object的话比new少了Animal本身属性的复制
一般的继承的话,除了继承原型属性/方法,实例的属性/方法也是需要继承的,主要是看应用场景

1.构造函数继承

核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

function Cat(){
  Animal.call(this);
  this.name ='Tom';
}
  var cat = new Cat();
console.log(cat,new Animal());
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

我们这里就看下console.log(new Cat(),new Animal());的打印结果,其余大家自己查看
在这里插入图片描述
这里调用了父级Animal函数,然后让父级函数本身的this指向变成了子级Cat的实例对象,相当于父级的所有的属性和方法在子级Cat函数里再次声明了一次。但是这种方式也有弊端

在这里插入图片描述
可以发现,当我们在原型链上添加属性和方法时,子级并没有继承父级的属性和方法总结如下:
特点:

  1. 解决了子类实例共享父类引用属性的问题
  2. 创建子类实例时,可以向父类传递参数
  3. 可以实现多继承(call多个父类对象)

缺点:

  1. 实例并不是父类的实例,只是子类的实例
  2. 只能继承父类在构造函数里声明的属性和方法,不能继承父级原型链上的属性和方法
  3. 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能

推荐指数:★★(缺点3)

2.原型链继承

核心: 将父类的实例作为子类的原型

    Animal.prototype.body = ['head','arm'];
   function Cat() {
      this.name = 'Tom';
    }
    Animal.prototype.eat = function () {
      console.log('i can eat')
    }
    Cat.prototype = new Animal();
    var cat = new Cat();
    console.log(cat ,new Animal());
    console.log(cat instanceof Animal); //true 
    console.log(cat instanceof Cat); //true
    var cat1 = new Cat();
    var cat2 = new Cat();
    cat1.body.push('foot')
    console.log(cat1,cat2);

这种方式可以继承原型链上的属性,但是同样有弊端
在这里插入图片描述
我new了两个cat1,cat2实例对象后,改变其中一个对象的属性,另外一个对象也会受到影响:总结
特点:

  1. 非常纯粹的继承关系,实例是子类的实例,也是父类的实例
  2. 父类新增原型方法/原型属性,子类都能访问到
  3. 简单,易于实现

缺点:

  1. 可以在Cat构造函数中,为Cat实例增加实例属性。但要新增原型属性和方法,则必须放在new Animal()这样的语句之后执行
  2. 无法实现多继承
  3. 来自原型对象的所有属性被所有实例共享
  4. 创建子类实例时,无法向父类构造函数传参

推荐指数:★★(3、4两大致命缺陷)

3.组合继承

核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用

  function Cat() {
      Animal.call(this);
       instance.name = 'Tom';
  }
  Animal.prototype.eat = function () {
    console.log('i can eat');
  }
  Cat.prototype = Object.create(Animal.prototype); //组合继承也是需要修复构造函数指向的
  Cat.prototype.constructor = Cat;
  var cat1 = new Cat();
  var cat2 = new Cat();
  cat1.body.push('foot')
  console.log(cat1,cat2)

组合方式排除了构造函数继承和原型链继承的弊端,是JS中最常用的继承模式了 总结:
特点:

  1. 弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法
  2. 既是子类的实例, 也是父类的实例
  3. 不存在引用属性共享问题
  4. 可传参
  5. 函数可复用

缺点:

  1. 调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

推荐指数:★★★★(仅仅多消耗了一点内存)

4.class继承

核心:class 是ES6新增的语法 直接class 创建一个类,使用extends来继承。具体看廖学峰大神的讲解

  class  Animal{
    constructor() {
       this.name = 'Tom';
    }
    play() {
          console.log('animal')
    }
  }
 
  class Cat extends Animal{
      constructor(type) {
        super(type);
        this.type ='cat'
      }
  }
  var cat = new Cat();

总结:最方便快捷的继承方式,但是仅支持ES6及以上版本,所以要考虑兼容性问题,

5.实例继承

核心:为父类实例添加新特性,作为子类实例返回

function Cat(){
  var instance = new Animal();
  instance.name =  'Tom';
  return instance;
}
var cat = new Cat();
console.log(cat );
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // false

在这里插入图片描述
总结:
特点:

  1. 不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果

缺点:

  1. 实例是父类的实例,不是子类的实例
  2. 不支持多继承

推荐指数:★★

6 拷贝继承

核心:循环父级

function Cat(){
  var animal = new Animal();
  for(var p in animal){
    Cat.prototype[p] = animal[p];
  }
  Cat.prototype.name =  'Tom';
}
var cat = new Cat();
console.log(cat);
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

特点:

  1. 支持多继承

缺点:

  1. 效率较低,内存占用高(因为要拷贝父类的属性)
  2. 无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)

推荐指数:★(缺点1)

7.寄生组合继承

核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}
(function(){// 创建一个没有实例方法的类
  var Super = function(){};
  Super.prototype = Animal.prototype;
  Cat.prototype = new Super();
  Cat.prototype.constructor = Cat;
})();
var cat = new Cat();
console.log(cat);
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true

特点:

  1. 堪称完美

缺点:

  1. 实现较为复杂

推荐指数:★★★★(实现复杂,扣掉一颗星)

请添加图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JS实现继承的几种方式 的相关文章

  • 通过git下载github分支(最详细)

    文章目录 一 git下载指定分支代码到本地A 前提 xff1a B 具体步骤 xff1a 二 git下载github所有分支代码到本地具体步骤 xff1a 一 git下载指定分支代码到本地 任务一 xff1a 下载地址为https gith
  • CSS基线对齐的理解以及处理

    相信大家都会遇到同行不同盒子中文本的内容不能对齐的情况 xff0c 而不知道这是为何 xff1f 其实这是因为基线对齐的原因 什么是基线对齐 xff1f 先让我们来看一张图片 xff1a 到这里我们的疑惑是不是少了一些 xff1f 基线对齐
  • Eigen求解大型稀疏对称矩阵(Cholesky分解)

    参考自Eigen文档 代码如下 xff1a span class token macro property span class token directive hash span span class token directive ke
  • CMake的基本使用方法与install命令

    源代码 main cpp文件如下 span class token macro property span class token directive hash span span class token directive keyword
  • docker常用命令总结

    docker常用命令总结 span class token function uname span span class token parameter variable r span span class token comment 查看
  • 基于STC15的飞控设计(1)飞控电路设计

    前言 学校举办的无人机比赛 xff0c 要求使用stc15系列芯片设计飞控 xff0c 然后完成一台四轴的无人机进行穿越障碍的比赛 xff0c 第一次设计飞控 xff0c 如果有什么设计得不好的希望大家多多指教 这个博客算是制作流程的记录
  • STM32F407霸天虎FreeRTOS学习笔记——移植FreeRTOS到开发板上

    STM32F407霸天虎FreeRTOS学习笔记 移植FreeRTOS到开发板上 FreeRTOS源码获取移植第一步 xff1a 创建文件夹Keilmain c 实验效果 FreeRTOS源码获取 在移植之前 xff0c 首先要获取到 Fr
  • 倒立摆及其应用//2021-2-23

    前言 xff1a 以前搞电赛的时候搞过Pid平衡小车 xff0c 倒立摆基本实现方法与平衡小车差不多 xff0c 有一次刚院跑到实验室唠嗑 xff0c 问你知不知道倒立摆的应用 xff1f 我说不知道 xff0c 他说航天火箭 xff0c
  • TypeError: Cannot convert a symbolic Keras input/output to a numpy array.

    问题类型 TypeError Cannot convert a symbolic Keras input output to a numpy array This error may indicate that you re trying
  • 自己的学习记录

    从今天开始学习如何使用Java来写数据库课程设计的作业 xff01 xff01 xff01
  • Tsai分享:资源分享(1)——视觉SLAM十四讲及视频

    Tsai分享 xff1a 资源分享 xff08 1 xff09 视觉SLAM十四讲及视频 一 视觉SLAM十四讲 如若转载请附上链接 xff1a https blog csdn net weixin 43338642 article det
  • pycharm如何查看python文件的工作目录

    在找bug的过程中发现python文件的工作目录和存放目录地址有可能是不一样的 xff0c pathlib路径操作中的pathlib Path cwd 获取的是工作目录而不是存放目录地址发现工作目录和存放目录地址不同的时候一定要修改过来 x
  • C++中vector的用法详解

    文章目录 构造函数增加函数删除函数遍历函数判断函数大小函数交换函数赋值函数改变空间 构造函数 span class token comment vector 创建一个空vector span vector span class token
  • 华为技术面

    文章目录 手撕代码流程题目描述方法介绍面试官评价思维扩展 项目描述技术问题内存说明下C 43 43 的内存分配情况 xff0c 栈和队列的区别以及程序员如何分配回收内存 xff1f C 43 43 程序员和Java程序员有一个很大的区别 x
  • 华东师范大学计算机学硕2023考研经验贴

    文章目录 1 个人经历1 1 一战1 2 二战1 3 心态 2 初试2 1 政治2 2 英语2 3 数学2 4 408 3 复试3 1 机试A 数字猜想B 特殊质数C 最小字符串D 数字排序E 整数分解 3 2 英语面试3 3 综合面试 1
  • Go后端部署服务器

    go后端部署服务器方式一 xff1a xff08 最简单 xff09 和暑假做重点场所项目部署一样 xff0c 简单 xff0c 无脑 xff0c 手动 xff0c 麻烦 span class token number 1 span spa
  • 数据分析实用python程序

    文章目录 1 pdf转txt2 判断txt文件是否为空3 获取txt文件每一行4 获取文件夹所有文件名5 读写xlsx表格6 遍历txt每个字符7 字符串中字符替换 1 pdf转txt span class token comment de
  • 51单片机之数码管

    1 静态数码管原理图 LED数码管根据LED的不同接法分为两类 xff1a 共阴和共阳 为了显示数字或字符 xff0c 必须对数字或字符进行编码 七段数码管加上一个小数点 xff0c 共计8段 因此为LED显示器提供的编码正好是一个字节 共
  • 银行排队模拟(队列)

    银行排队模拟程序 队列类Queue ifndef span class token constant QUEUE H span define span class token constant QUEUE H span struct Rec
  • C/C++中struct和class的区别

    目录 struct class struct和class的区别 struct struct是描述一个数据结构的集合 xff0c 像一周有七天 xff0c 你可以把一周看成是一个结构体 xff0c 然后在结构体里面定义一个数组来存放这个七天

随机推荐

  • java枚举(enum)使用详解

    文章目录 前言一 枚举类型定义二 访问成员三 遍历四 在switch xff08 xff09 中使用枚举五 方法1 内置方法1 1 ordinal 用于返回成员的索引1 2 compareTo 用于比较枚举类型中两个成员的索引值1 3 va
  • 分析url从输入到展过程中的页面优化、performance

    浏览器会开启一个线程处理URL请求 url从输入到展示页面的过程 1 输入网址 2 DNS解析 3 建立tcp连接 xff08 请求队列queuing 请求等待stalled 4 客户端发送HTPP请求 5 服务器处理请求 6 服务器响应请
  • 双重锁单例模式

    不忘初心 xff0c 思考梦开始的地方 普通的懒汉式和饿汉式都不用管 简单实现一下线程安全的方式 span class token keyword public span span class token keyword class spa
  • VScode神仙插件,程序员必备

    前言 Visual Studio Code VS Code 是微软2015年推出的一个轻量但功能强大的源代码编辑器 xff0c 基于 Electron 开发 xff0c 支持 Windows Linux 和 macOS 操作系统 它内置了对
  • 【Java】使用Java实现爬虫

    文章目录 使用Java实现爬虫一 HttpClient实现模拟HTTP访问1 1 HttpClient1 2 引入依赖1 3 创建简单的请求操作1 3 1 创建实例1 3 2 Jsoup应用 1 4 爬取过程中可能出现的问题1 4 1 JS
  • STM32 HAL库+ESP8266+华为云物联网平台

    文章内容 xff1a STM32 HAL库通过串口发送AT指令完成与ESP8266的控制实现接入华为云物联网平台 xff0c 并完成基本通信与控制 xff0c 包括设备属性上报和命令下发解析与响应 文末获取 STM32 HAL库 43 ES
  • MySQL事务篇

    文章目录 说明 xff1a 事务篇一 事务隔离级别是怎么实现的 xff1f 二 MySQL 可重复读隔离级别 xff0c 完全解决幻读了吗 xff1f 说明 xff1a 此类文章是为小林coding的图解MySQL xff0c 所简写 xf
  • Android studio TCP网络调试助手应用开发(支持TCP Server与Client切换)

    在前几篇的文章中带大家完成了基于TCP的物联网安卓应用开发 xff0c 教程内容是创建了一个TCP客户端并连接服务器完成数据通信的过程 xff0c 后不久又发布了一个ESP8266创建TCP 服务器与安卓的客户端进行通信的一个文章 xff0
  • 【FreeRTOS】中断管理

    在介绍本文之前 xff0c 向大家推荐个非常容易入门的人工智能学习网站 xff0c 建议点击收藏 目录 xff1a 1 前言2 内核提供两套API2 1 优点2 2 缺点2 3 常用API函数列表2 4 pxHigherPriorityTa
  • 【嵌入式基础】内存(Cache,RAM,ROM,Flash)

    1 前言 最近在看赛普拉斯的一款芯片CYW8019规格书 xff0c 里面有好几个内存的关键字 xff08 如下图的右上方 xff09 xff0c 本文将聊它们的含义和作用 2 Cache Cache是集成在CPU内部的极高速缓存 一般来讲
  • 使用Promise解决多个请求数据并发问题

    首先引用一下阮一峰大佬的一段话 xff1a Promise xff0c 简单说就是一个容器 xff0c 里面保存着某个未来才会结束的事件 xff08 通常是一个异步操作 xff09 的结果 从语法上说 xff0c Promise是一个对象
  • 1. KVM虚拟化学习

    1 什么是虚拟化 虚拟化 xff0c 通过模拟计算机的硬件 xff0c 来实现同一台计算机上运行多个不同的操作系统的既技术 2 为什么要使用虚拟化 为了充分利于资源 xff0c 软件运行环境的隔离 xff0c 只要有虚拟化才能实现 虚拟化提
  • 二次再散列法

    散列表 设所有可能出现的关键字集合记为U 简称全集 实际发生 即实际存储 的关键字集合记为K xff08 K 比 U 小得多 xff09 散列方法是使用函数h将U映射到表T 0 m 1 的下标上 xff08 m 61 O U xff09 这
  • CICD中clang-tidy静态语义检查

    教程 xff1b https hokein github io clang tools tutorial 要用clang tidy首先要在电脑上安装clang tools Linux Ubuntu系统 span class token fu
  • Vscode 设置clang-format

    用户设置与工作空间设置 VS Code提供了两种设置方式 xff1a 用户设置 xff1a 这种方式进行的设置 xff0c 会应用于该用户打开的所有工程 xff1b 工作空间设置 xff1a 工作空间是指使用VS Code打开的某个文件夹
  • 同步异步电机ADRC控制系统仿真

    之前一直使用PI控制器做异步电机矢量控制 xff0c 最近想把ADRC控制也放到异步电机矢量控制上去 xff0c 所以对其进了仿真 xff0c 可遇到了一个一直没有解决掉的问题 xff0c 现记录下来 xff0c 请各位先辈进行指教以及为遇
  • 大疆A型板使用经验分享(八)——FreeRTOS操作系统的使用

    一 freeRTOS操作系统 操作系统 operating system 本质上是一个帮助用户进行功能管理的软件 操作系统运行在硬件之上 为其他工作的软件执行资源分配等管理工作 一般称呼不使用操作系统的单片机开发方式为 裸机开发 当进行裸机
  • MySQL锁篇

    文章目录 说明 xff1a 锁篇一 MySQL有那些锁 xff1f 二 MySQL 是怎么加锁的 xff1f 三 update 没加索引会锁全表 xff1f 四 MySQL 记录锁 43 间隙锁可以防止删除操作而导致的幻读吗 xff1f 五
  • C++学习笔记

    文章目录 一 基础入门1 常量2 关键字3 数据类型3 1 整型3 2 浮点型3 3 字符型3 4 字符串类型3 5 布尔类型 4 数据的输入与输出5 运算符6 数组6 1 一维数组6 2 二维数组 7 函数8 指针9 结构体 二 核心编程
  • JS实现继承的几种方式

    JS继承的实现方式 堪称最全最详细 前沿看js继承这块时我看的几个教程都是说的很简单或者是没有说全就自行百度看了好多总结了下有 xff1a 1 构造函数继承 2 原型链继承 3 组合继承 4 class继承 5 实例继承 6 拷贝继承 7