深入解析JavaScript中的原型继承

🧑‍🎓 个人主页:《爱蹦跶的大A阿》

🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》

​ 

✨ 前言

        原型继承是JavaScript中的一种非常重要的继承方式。理解原型继承对于JavaScript开发非常关键。

        本文将详细介绍原型继承的实现原理、使用方式以及优缺点,帮助大家全面理解这一核心知识点。

✨ 正文

原型继承的工作原理

JavaScript对象都有一个内置的__proto__属性,指向创建该对象的构造函数的原型对象prototype。当访问一个对象的属性时,如果这个对象没有该属性,就会继续在__proto__这条原型链上查找,这就是原型继承的工作原理。

举例来说:

function Animal(name) {
  this.name = name; 
}

Animal.prototype.walk = function() {
  console.log(`${this.name} is walking!`);
}

let dog = new Animal('Dog');
dog.walk(); // Dog is walking!

这里dog继承了Animal.prototype上的walk方法。

原型继承的实现

实现原型继承常用的两种模式:

  • 构造函数+原型方法
  • 对象创建+指定原型

第一种通过构造函数创建对象实例,原型上定义共享方法:

function Super() {}
Super.prototype.foo = function() {}

function Sub() {}
Sub.prototype = new Super();

let sub = new Sub();
sub.foo(); // 原型方法

 第二种是创建对象并指定其原型:

let superObj = {
  foo: function() {}
};

let subObj = Object.create(superObj); 
subObj.foo(); // 原型方法

原型继承的优缺点

原型继承的主要优点包括:

  • 父类方法可以被复用
  • 实现了接口继承
  • 符合OOP中继承的思想

缺点主要有:

  • 父类属性被所有实例共享
  • 不能实现多继承
  • 来源不清晰,调试困难

 深度解析

除了原型继承的基本内容,这里我再介绍几个更深入的点:

  • 原型链

        原型对象也可以有原型,这样会形成一个原型链,用于模拟继承等功能,原型对象自己也是一个对象,拥有自己的原型,这样就可以形成一个原型链:

function Super() {}
function Sub() {}

Sub.prototype = new Super(); 
Sub.prototype.constructor = Sub;

let sub = new Sub();

        这里Sub.prototype原型对象继承自Super,就形成了原型链。 

  • instanceof

        通过实例的__proto__链来判断构造函数的原型是否存在于该链中,实现instanceof操作,instanceof通过检查对象的原型链中是否存在构造函数的prototype来判断关系:

function Foo() {}
let foo = new Foo();

foo instanceof Foo; // true
  • 原型污染

        直接修改原型对象会影响所有实例,需要防止原型被污染,直接修改原型对象会影响所有实例:

function Foo() {}
let foo1 = new Foo();
let foo2 = new Foo();

Foo.prototype.test = 'Hello';

foo1.test; // 'Hello'
foo2.test; // 'Hello'

        需要利用Object.create()避免直接修改原型对象。 

  • 寄生组合式继承

        结合构造函数继承和原型继承的优点,实现更优雅的继承方式。

function Super() {
  this.superValue = 'hello';
} 

Sub.prototype = Object.create(Super.prototype); 
Sub.prototype.constructor = Sub;

function Sub() {
  Super.call(this);
}
  • 原型继承的性能

        通过缓存访问原型的结果可以提高原型访问的性能。

  • 与类继承的区别

        ES6类继承是在原型继承的基础上实现的语法糖。

  • 相关设计模式

        原型模式、混入模式都利用了原型继承实现。

✨ 结语

       原型继承是JavaScript实现继承的主要方式。理解其工作原理和应用方式对掌握JavaScript是非常重要的。

        当然,过度使用原型继承也会带来一些问题。实际项目中要灵活运用,可以搭配构造函数等方式组合使用。

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习JavaEE的日子 day13补 深入类加载机制及底层

深入类加载机制 初识类加载过程 使用某个类时,如果该类的class文件没有加载到内存时,则系统会通过以下三个步骤来对该类进行初始化 1.类的加载(Load) → 2.类的连接(Link) → 3.类的初始化(In…

geemap学习笔记050:掩膜操作

前言 在进行相关操作时,往往需要对一部分范围的值进行掩膜,以去掉这一部分的值。Earth Engine中已经提供了相关的掩膜操作,下面将会详细的介绍一下mask、selfMask、updateMask。 1 导入库并加载数据 import ee import geemapee.Initialize…

细说JavaScript的数据类型(JavaScript的数据类型详解)

在JavaScript中有六种不同的数据类型,六种数据类型又分为5种简单数据类型(基本数据类型)和1中复杂数据类型(引用数据类型),基本数据类型分为:字符串类型(string)、数值类…

基于频率滑动广义互相关的信号时延估计方法(MATLAB R2018A)

广义互相关(Generalized Cross-Correlation, GCC)方法是一种改进的互相关分析技术,用于更准确地估计信号的时间延迟。这种方法特别适用于噪声环境中的时延估计,因为它通过特定的加权处理提高了互相关函数的峰值的显著性&#xff0…

提升线上会议效率,解决Teams会议中常见网络问题

在企业组网场景中,在线会议是混合办公、跨地区办公模式下很重要的协作沟通手段,而在线会议如Teams这类应用对网络的实时性和即时性要求非常高,网络频繁中断、接入速度慢、登不进去等问题分分钟加剧用户的不满,导致汇报失败或者是交…

nexus3 npm-hosted仓库迁移

迁移背景: 从nexus 3.33 升级到 nexus 3.64 过程中,私服 npm-hosted 无法上传。由于这个 npm-hosted 和 npm-proxy 放的同一个 blob存储,无法单独拆除去,所以采用迁移的方式 迁移思路: down下来 npm-hosted 仓库&am…

【Java】HttpServlet类简单方法和请求显示

1、HttpServlet类简介🍀 Servlet类中常见的三个类有:☑️HttpServlet类,☑️HttpServletRequest类,☑️HttpResponse类 🐬其中,HttpServlet首先必须读取Http请求的内容。Servlet容器负责创建HttpServlet对…

WebGL中开发VR(虚拟现实)应用

WebGL(Web Graphics Library)是一种用于在浏览器中渲染交互式3D和2D图形的JavaScript API。要在WebGL中开发VR(虚拟现实)应用程序,您可以遵循以下一般步骤,希望对大家有所帮助。北京木奇移动技术有限公司&a…

docker环境下mongo副本集的部署及异常修复

最近更换了办公地点。部署在本地docker环境里的mongo数据库不能使用了。原因是本地的ip地址变更。以前的mongo副本集的配置需要更新。处理完后,索性重新记录一下mongo副本集在docker中的部署流程。 mongo的事务及副本集 我们先了解一下什么是事务,事务…

虚拟化网络

vm1和vm2通过虚拟交换机与主机进行交换, 虚拟交换机:(通过软件虚拟出来的交换机) 1、LinuxBridge虚拟交换机 2、OVS(Open Virtual Switch)虚拟交换机 虚拟机的传输是通过虚拟交换机,然后连到…

Servlet 预览pdf

一、背景 上篇文章介绍了图片的预览,这篇我们介绍下 pdf 文件的预览,pdf 预览在实际开发中用的还是比较多的,比如很多文件协议、合同都是用pdf 格式,协议预览就需要我们做 pdf 预览了。 二、实操 其实在上篇文章最后已经说了常用…

在Android原生项目中 创建 Flutter模块

前言 应用场景:在已有的Android原生项目中,引入Flutter模块,摸索了两天,终于给整出来了; 如果是新项目,最好直接创建Flutter项目,然后在Fluter的 android / ios目录中,写原生代码&…

常见的设计模式(模板与方法,观察者模式,策略模式)

前言 随着时间的推移,软件代码越来越庞大,随着而来的就是如何维护日趋庞大的软件系统。在面向对象开发出现之前,使用的是面向过程开发来设计大型的软件程序,面向过程开发将软件分成一个个单独的模块,模块之间使用函数…

Spark SQL函数定义

目录 窗口函数 SQL函数分类 Spark原生自定义UDF函数 Pandas的UDF函数 Apache Arrow框架基本介绍 基于Arrow完成Pandas DataFrame和Spark DataFrame互转 基于Pandas完成UDF函数 自定义UDF函数 自定义UDAF函数 窗口函数 分析函数 over(partition by xxx order by xxx [as…

MathType2024下载安装系统要求及新版本功能介绍

MathType 7应用介绍 MathType可适用于800软件应用程序和网站,支持在任何文字处理软件、演示程序、页面程序、HTML编辑工具及其它类型的软件,用来建立公式。 应用范围:期刊杂志、科研机构、教育教学、工程学、统计学、论文、报告写作、word文…

新数智空间:阿里云边缘云持续保持中国公有云市场第一

全球领先的 IT 市场研究和咨询公司 IDC 发布 《中国边缘云市场解读(2023H1)》报告 中国边缘公有云服务市场 阿里云持续第一 稳居市场第一,“边缘”逆势生长 近日,全球领先的 IT 市场研究和咨询公司 IDC 最新发布《中国边缘云市…

20240117-【UNITY 学习】增加墙跑功能和跳墙功能

替换脚本PlayerCam_01.cs using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening;public class PlayerCam_02 : MonoBehaviour {// 视觉灵敏度参数public float sensX 400;public float sensY 400;// 视角垂直旋转角度限制publ…

IDEA怎么用Devtools热部署

IDEA怎么用Devtools热部署 大家知道在项目开发过程中,有时候会改动代码逻辑或者修改数据结构,为了能使改动的代码生效,往往需要重启应用查看改变效果,这样会相当耗费时间。 重启应用其实就是重新编译生成新的Class文件&#xff0…

axios的原理及源码解析

面试官:你了解axios的原理吗?有看过它的源码吗? 一、axios的使用 关于axios的基本使用,上篇文章已经有所涉及,这里再稍微回顾下: 发送请求 import axios from axios;axios(config) // 直接传入配置 axio…

C语言数据结构之线性表-顺序表篇

星光不负赶路人 江河眷顾奋楫者 🎥烟雨长虹,孤鹜齐飞的个人主页 🔥个人专栏 期待小伙伴们的支持与关注!!! 线性表的简介# 线性表(linearlist):是n个具有相同特性的数据元…