[前端语法]js原型链有关的继承问题

news2024/11/25 1:44:57

深夜反而思维更活跃一些

(1)js中的原型链

js中存在一个名为原型链的机制,其特点如下

加入一个方法A,A方法一个属性为prototype,这个属性会指向某个对象,也成为A类对象的原型对象.

当我们根据A这个方法生成一个对象a,那么a的原型(proto)属性即为这个对象

a可以调用一些原型的属性和方法,另外,这也是一些方法查找的原理

(2)js相关的五种继承

继承一共有五种,这五种继承其实都是"属性追加"和"原型链"两个特殊功能的集合体,借用这两个特性实现继承的效果,下面讲解一下有关的思路和勘误

  • 原型链继承

原型链继承指的就是,给创造对象的方法指定一个原型对象

//创建父类方法并且创造一个父类对象
function Parent(){
     this.name="kevin"
}

let p=new Parent

//子类
function Child(){

}

//在创建方法这里指定继承的原型
Child.prototype=p

//创建两个对象
let c1=new Child()
let c2=new Child()


//则有
console.log(c1.__proto__)//p
console.log(c2.__proto__)//p

 这种继承比较好理解,但是有个缺点就是图里面这种情况

console.log(c1.name)  //"kevin"
console.log(c2.name)  //"kevin"

 这种情况下继承的原型是共有的,属性也是一致的,因为子类对象没有这种属性,所以会根据原型链网上寻找这种属性.

  • 构造函数继承

构造函数继承在原理上很类似于其他oop语言的继承方式,即在构造子类对象的时候,优先构造父类对象.

//创建父类方法并且创造一个父类对象
function Parent(name){
     this.name=name
}


function Child(name,age){
     Parent.call(this,name)
     this.age=age
}


//创建两个对象
let c1=new Child("张三",12)

console.log(c1.name) //"张三"

 解释一下这段代码中出现的call语法,call语法是一种传递上下文的方法,在这里对于Parent构造方法使用了call,并且传入了参数this以及name,这个this就是Child的上下文对象

这个时候调用的Parent这个函数,里面的this指向的其实就算一个child对象了

这种继承方法无法像原型链或者es6新增的那种继承一样,只能算是一种"属性追加",这一点和后面的寄生继承一样

  • 组合构造继承

把以上的两种方式给总和起来,一方面,使用构造函数的方法来给对象增加属性.

另一方面 ,使用原型链,给父类构造方法增加一个原型对象,这样可以达成这样的效果

//创建父类方法并且创造一个父类对象
function Parent(name){
     this.name=name
}

Parent.prototype=A      //对象A中有个属性address

function Child(name,age){
     Parent.call(this,name)
     this.age=age
}


//创建两个对象
let c1=new Child("张三",12)
let c2=new Child("李四",12)

//这个是不一样的
console.log(c1.name) //"张三"
console.log(c2.name) //"李四"

//这个是一样的
console.log(c1.address) //"一样的"
console.log(c2.address) //"一样的"
  • 寄生继承

寄生继承和前面的借用构造函数继承一样,本质上不是利用父子类之间的关系,而是利用一些方法进行追加.区别在于,借用构造函数的追加方法是把上下文对象传入别的构造方法中进行追加

而寄生继承则是在一个方法内部,对传进来的方法,先生成对象,然后直接追加属性

function createObj(Obj){
   let o=Object.create(Obj)
   //直接对根据方法生成的对象o进行追加
   return o
}
  • 组合寄生继承(综合上面的方法)

举一个例子,这些东西的应用还是挺灵活的

使用构造函数的方法追加一些数据,然后使用寄生继承的方法增加原型链

//创建父类方法并且创造一个父类对象
function Parent(name){
     this.name=name
}

//子类的方法中使用了借用构造函数继承
function Child(name){
     Parent.call(this,name)
}

//创建一个,原型对象为o的类
function create(o){
     function F(){}
     F.prototype=o
     return new F()
}

function Prototype(child, parent) {
    var p = object(parent.prototype);
    p.constructor = child;
    child.prototype = p;
}

//给Child新建了一个原型对象,这个原型对象就是Parent的原型对象
Prototype(Child, Parent);

补充:棍鱼Prototype这个方法,可以这样子解释

首先,我们使用组合式继承,已经对Child函数扩展了属性,这种情况下,我们就没必要指定原型为Parent对象,Parent的原型有一个公共方法

我们在使用了一个空白对象F作为中间介质,避免了创建无用的Parent

区别画图展示

简单做个总结:

原型链是最贴近继承含义的,因为这东西会根据原型链向上找属性,属于纵向的

而另外两种,则是在原本的基础上扩展/追加属性,属于横向的,是一种伪继承 

 

(3)一道和原型有关的例题(来自leetcode)

[leetcode]前端

 这题对于基础要求...其实很高的,因为一般些js都自由散漫惯了..........真的

这题的输入是一个对象,一个生成方法,判断对象是否由这个方法或者其他方法生成

(1)方案1,也是我使用的一种,比较原型对象

首先先排除特殊情况,也就是对象为null或者方法为null,这种要返回false

var checkIfInstanceOf = function(obj, classFunction) {
      if(obj==null || classFunction==null) return false;//第一种情况,对象和类均为空的时候
      let a=Object.getPrototypeOf(obj); //先找到obj的原型对象
      //然后开始遍历原型链
      while(a!==null){   
          if(a === classFunction.prototype){
            return true;
          }
          a=Object.getPrototypeOf(a);
      }
      return false;
}

(补充内容:除了可以用属性proto来获取原型,还可以直接使用函数Object.getPrototype(&&)来获取)

另外这个例题也带来了一个衍生的问题:

[如何判断一个对象属于哪个类,怎么实现?]

(1)判断基本类型可以使用函数typeof

但是这个函数有一个历史性的缺陷,  typeof(null)===object......这确实有问题,但是已经没法改了

(2)利用原型链来判断 instanceof,实现原理和上面的题目是一样的

剩下还有别的一些方法

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

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

相关文章

【cropperjs】优秀、优雅的前端图片裁剪库

下载 npm i cropperjsnpm官网- https://www.npmjs.com/package/cropperjs cropperjs关键参数 aspectRatio 图片裁剪比例 默认值 :NaN作用:图片裁剪比例值:自定义裁剪比例,例如1 / 1 , 4 / 3 , 16 / 9等 viewMode 裁剪模式 默认…

代码随想录算法训练营第二十七天| 39. 组合总和、 40.组合总和II、 131.分割回文串

组合总数 题目链接:力扣 这题和之前题目的区别在于,本题没有数量要求,可以无限重复的取某一元素,但是对元素的总和有限制,这就说明了递归的限制不在于层数,而是选取元素的总和超过target就返回 终止条件为…

【owt】WebrtcNode, subscirbe-sdp offer 流程(2)

流程图 创建MediaStream, MediaStream一方面作为从VideoFramePacketizer接收到媒体数据; 创建VideoFramePacketizer,MediaStream 把sink 注册到VideoFramePacketizer,这样VideoFramePacketizer(继承了MediaSource&…

upload靶场通关(12-21关)

Pass-12(白名单校验(GET 型 0x00 截断)) 先看提示: 一头雾水,只知道了上传路径是可控的 查看源码: 能看懂就看看,反正我是看了同学的笔记得知这是白名单,按照文件名进行…

Customizable constraint systems for succinct arguments学习笔记(1)

1. 引言 微软研究中心Srinath Setty、a16z crypto research 和 Georgetown University Justin Thaler、Carnegie Mellon University Riad Wahby 20203年论文《Customizable constraint systems for succinct arguments》。 在该论文中,介绍了Customizable constra…

CMake学习(1): CMake基本使用

https://subingwen.cn/cmake/CMake-primer/ 1. CMake 概述 CMake是一个项目构建工具,并且是跨平台的。Cmake跟Makefile其实是差不多的,只不过makefile更底层些。大多是 IDE 软件都集成了 make,比如:VS 的 nmake、linux 下的 GNU…

单链表OJ题:LeetCode--141.环形链表

朋友们、伙计们,我们又见面了,本期来给大家解读一下LeetCode中的第141道单链表OJ题,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! 数据结构与算法专栏:数据结构与算法 个 …

龙岗区五联土地整备利益统筹项目,集体物业集中签约仪式

五联土地整备利益统筹项目启动以来街道高度重视相关工作开专题会、建工作组、设党支部把征拆工作一项项推进 截至6月1日已完成: 清租签约73户,面积9.55万m(意向签约17户,约1.66万m) 私人住宅业主补偿安置签约8户&…

Java语言----反射、枚举以及lambda表达式

目录 一.反射 1.1反射的基本情况 1.2反射中最重要的类 1.2.1 Class类 1.2.2Field类 1.2.3Constructor类 1.2.4Methood类 1.3反射优缺点 二.枚举 2.1概念 2.2枚举(enum)类方法 2.3枚举的构造 三.Lambda表达式 3.1Lambda介绍 3.2 函数式接…

AI实战营:深度学习预训练与MMPreTrain

目录 一、MMPretrain算法库介绍 二、经典主干网络 残差网络ResNet(2015) Vision Transformer(2020) 三、自监督学习 四、多模态算法 一、MMPretrain算法库介绍 算法库与任务组成&框架概览 预训练工具箱MMPretrain Python推理API 环境搭建 O…

数据结构与算法·第4章【串】

串是有限长的字符序列,由一对单引号相括,如: “a string” 可以理解为c的 s t r i n g string string 基本操作 S t r A s s i g n , S t r C o m p a r e , S t r L e n g t h , C o n c a t , S u b S t r i n g StrAssign,StrCompare,StrLength,Conc…

大数据技术——使用IDEA开发Scala程序

目录 一、使用IDEA开发WordCount程序... 3 二、实验目的... 3 三、实验要求... 3 四、实验环境... 3 五、实验步骤... 3 4.1.1启动IDEA并创建一个新项目WordCount 3 4.1.2为WordCount项目添加Scala框架支持... 7 4.1.3数据准备... 8 4.1.4设置项目目录... 9 4.1.5新建…

webAPI学习笔记4——PC端网页特效

目录 1. 元素偏移量 offset 系列 1.1 offset 概述 1.2 offset 与 style 区别 offset style !!!!!!!案例:获取鼠标在盒子内的坐标 !!!!!&…

Jeston Orin Nnao 安装pytorch与torchvision环境

大家好,我是虎哥,Jeston Orin nano 8G模块,提供高达 40 TOPS 的 AI 算力,安装好了Jetpack5.1之后,我们需要配置一些支持环境,来为我们后续的深度学习开发提供支持。本章内容,我将主要围绕安装对…

OCR图片文字识别,人工手动图片标注软件安装过程

OCR图片文字识别,人工手动图片标注软件安装过程,本章关注标注软件的安装,启动过程 1. 下载 anaconda anaconda 下载慢的问题: 使用国内镜像地址下载: https://mirrors.bfsu.edu.cn/anaconda/archive/ https://www.ana…

OpenMMLab-AI实战营第二期——4.深度学习预训练与MMPretrain

文章目录 1. MMPreTrain算法库介绍1.1 算法库与任务组成1.2 框架概览 2. 经典主干网络2.1 ResNet2.2 Vision Transformer 3. 自监督学习3.1 SimCLR3.2 MAE3.3 iBOT 4. 多模态算法4.1 CLIP4.2 BLIP 视频链接:b站-深度学习预训练与MMPretrain 1. MMPreTrain算法库介绍…

NvM学习笔记(一)以TC387为例,分析为什么要使用Flash 模拟 EEPROM ?

在嵌入式软件系统中,管理非易失性的数据存储,如在系统启动时,从非易失性存储器中读取一些关键数据,在系统关闭阶段,同步应用程序RAM区的数据到非易失性存储器中,是一项十分必要的工作。 目前行业内用的最广…

Linux :: 时间日历指令【3】:cal 指令:查询当日是今年的第几天、输出当前月历、指定月历、输出当前年历、指定年历

前言:本篇是 Linux 基本操作篇章的内容! 笔者使用的环境是基于腾讯云服务器:CentOS 7.6 64bit。 学习集: C 入门到入土!!!学习合集Linux 从命令到网络再到内核!学习合集 目录索引&am…

Redis分段锁实现超高并发秒杀

参考尼恩著:《Java高并发核心编程》 技术自由圈 业务情景 还是秒杀场景,假设抖音直播间小杨哥上架6000单螺蛳粉,价格9.9买10包,限时1分钟秒杀,此时准备秒杀的人有1万人。我们首先从技术上来看看如果不进行优化是否可以…

控制四旋翼飞行器以进行多目标航点导航的MPC算法(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…