JS学习笔记 原型链和利用原型实现继承

article/2025/9/13 1:17:56

原型链

原型链是一种关系,实例对象和原型对象之间的关系,关系是通过原型(__proto__)来联系的


实例对象中有__proto__,是对象,叫原型,不是标准的属性,浏览器使用,并且有的游览器不支持
构造函数中有prototype属性,也是对象,叫原型

注意 原型中的方法是可以互相访问的

实例代码

 function Animal(name,age){this.name=name;thia.age=age;}//在原型中添加方法Animal.prototype.eat=function(){console.log("动物吃草")this.play()}Animal.prototype.play=function(){console.log("玩啥呢")}

原型的简单语法  

利用原型共享数据

第一种 写法

 function Student(name,age,sex){this.name=name;this.age=age;this.sex=sex;}Student.prototype.height="188"Student.prototype.weight="55kg"Student.prototype.study=function(){console.log("好好学习i")}var stu=new Student("小红",20,"男")console.dir(stu)

结果

第二种 写法

 function Student(name,age,sex){this.name=name;this.age=age;this.sex=sex;}Student.prototype={height:"188",weight:"55kg",study:function(){console.log("好好学习i")}}var stu=new Student("小红",20,"男")console.dir(stu)

结果


我们会发现 两种写法还是有差别的  ,第二种写法会导致constructor构造器属性消失 所以我们得手动修改构造器指向

最终代码

function Student(name,age,sex){this.name=name;this.age=age;this.sex=sex;}Student.prototype={constructor:Student,height:"188",weight:"55kg",study:function(){console.log("好好学习i")}}var stu=new Student("小红",20,"男")console.dir(stu)

好了,这回有了


实例对象使用属性或方法的规则

实例对象使用的属性或方法,现在实例中查找,如果有则使用自身的属性或方法,
如果没有,则通过__proto__指向的原型对象 查找方法,找到则使用,
如果找不到则继续向__proto__寻找,直到未找到时报错

构造函数和实例对象和原型对象之间的关系

     构造函数可以实例化对象
     构造函数中有一个属性叫prototype,是构造函数的原型对象
     构造函数的原型对象(prototype)中有一个constructor 构造器,这个构造器指向的就是自己所在的原型对象所在的构造函数
     实例对象的原型对象(__proto__) 指向的是该构造函数的原型对象(prototype)
     构造函数的原型对象(prototype)中的方法是可以被实例对象直接访问

    


改变原型是否可以改变?

首先我们得知道构造函数和实例对象中的this 指向的是什么

这里我创建了自定义构造函数 Person ,并在内部输出了this 

并且在Person 的原型对象上添加了一个eat 方法,也输出了一个this,

接着我实例化了一个对象,并调用eat方法,

我们执行一下,查看结果如何


输出结果


由此得出
原型对象中方法中的this 就是实例对象

构造函数中的this就是实例对象


接下来我们尝试改变一下原型的指向

这段代码中,首先我定义了一个Person自定义构造函数,并且在原型上添加了一个eat方法

定义了一个Student 函数,在原型上定义了一个sayHi方法,

然后我将 Student的原型指向 了一个 Person的实例对象

接着实例化一个Student,接着分别在stu 实例上 尝试着调用 eat方法 和 sayHi 方法,

运行结果


到此我们可以确定,stu实例对象原型指向被下面这条代码改变了

Student.prototype=new Person(10);

总结

原型指向可以被改变的

实例对象的原型__proto__指向的是该对象所在的构造函数的原型对象

构造函数的原型对象(prototype)指向如果改变了,实例对象的原型(__proto__)指向也会发生改变

实例对象和原型对象之间的关系是通过__proto__ 原型来联系起来的,这个关系就是原型链

如果原型指向改变了,那么就应该再原型改变指向之后添加原型方法

那么sayHi方法则会创建在 new Person(10) 这个实例对象上

原型最终指向了哪里


实例对象中的__proto__指向的是构造函数的prototype

以此代码为例


测试一下



所以

per实例对象的__proto__ ---指向--->  Person.prototype的__proto__  ---指向--->  Object.prototype的__proto__ 是Null


查看了一下html的dom对象,这有很有意思的原型链


这里祭出祖传JPG


实现继承

小知识---->instanceof的判断方法:

从左边操作数的__proto__路线出发,从右边操作数的prototype出发,如果两条路线最终指向一个引用就是true了

1.利用 call 借用构造函数继承

优点:实现了继承属性,但值都不相同

缺点: 无法继承父级类别中原型上的方法

function Person(name,age,sex,weight){this.name=name;this.age=age;this.sex=sex;this.weight=weight;
}
Person.prototype.sayHi=function(){console.log("您好")
}function Student(name,age,sex,weight,score){//将当前实例对象传入Person 借过来使用一次来达到继承效果Person.call(this,name,age,sex,weight);this.score=score;
}var stu1=new Student("小明",10,"男","10kg","100")

2.  prototype 实现继承

利用prototype,将Student 的prototype 指向 Person 来达到继承效果,

优点:继承了父级原型上的方法

缺点:   实例化多个Student 都必须共用相同的name 和 age 

Student.prototype.constructor=Student

注意:   使用原型继承时,需要将构造器的指向更改回正确的指向

function Person(name,age){this.name=name;this.age=age;}Person.prototype.eat=function(){console.log("Person 吃饭")}function Student(num,score){this.num=numthis.score=score}//继承Student.prototype=new Person("小红",10)Student.prototype.constructor=Studentvar stu =new Student(2016002288,80)stu.eat()//Person 吃饭

3.组合继承

组合继承其实就是结合了上述的两种方法来实现继承,拥有两种方法的优点

function Person(name,age,sex){this.name=name;this.age=age;this.sex=sex;}Person.prototype.sayHi=function(){console.log("你好")}function  Student(name,age,sex,score){//借用构造函数Person.call(this,name,age,sex)this.score=score}// 改变了原型指向Student.prototype=new Person();//不传值Student.prototype.eat=function(){console.log("吃东西");}var stu=new Student("小黑",20,"男","100分")console.log(stu.name,stu.age,stu.sex,stu.score);stu.sayHi()//你好stu.eat()//吃东西

4.拷贝继承

类似于复制,把一个对象中的属性和方法直接复制到另一个对象中

function Person(){}Person.prototype.name="小红"Person.prototype.age=18function Student(){}var p=Person.prototype;var s=Student.prototype;for(key in p){s[key]=p[key]}console.dir(Student)
console


每次都要for in 好累 ,  可以进行优化封装一下

function extend(Child,Parent) {var p = Parent.prototype;var c = Child.prototype;for (var i in p) {c[i] = p[i];}//这个属性直接指向父对象的prototype属性,可以直接调用父对象的方法,为了实现继承的完备性,纯属备用性质c.par = p;}

5. 直接继承prototype

优点 : 效率比较高

缺点 : 因为相当于是个传址过程 所以修改Student的属性 Person 的也会被更改 

    function Person(){};Person.prototype.name="小红";Person.prototype.age=18;function Student(){};Student.prototype=Person.prototype;console.dir(Student);console.dir(Person);Student.prototype.age=25;
console



6.利用空对象作中介实现继承

用这种方式修改 Student 的prototype 不会影响到 Person的prototype

function Person(){};Person.prototype.name="小红";Person.prototype.age=11;function Student(){};var F=function(){};F.prototype=Person.prototype;Student.prototype=new F();Student.prototype.constructor=Student;Student.prototype.age=25;console.dir(Person)console.dir(Student)

console


封装一下

function extend(Child,Parent) {var F = function(){};F.prototype = Parent.prototype;Child.prototype = new F();Child.prototype.constructor = Child;Child.par = Parent.prototype;}

http://chatgpt.dhexx.cn/article/THZEhNl2.shtml

相关文章

Arduino基本知识(marlin固件配置)

初识arduino,根据mega2560(某宝可以买到)官网的100个管脚具体控制一句传输进行操作。 https://www.arduino.cc/en/Hacking/PinMapping2560 其管脚图如上所示。 首先在官网下载arduino的配套软件 https://www.arduino.cc/ 对于编程&#xf…

3D打印机硬件驱动-马林固件最新版本2.0.X中文注释(3)marlin 2.0.9.2 截至发稿时间2021年12月16日

/** * Marlin 3D Printer Firmware 头描述详见其他两个文件头描述 * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * * Based on Sprinter and grbl. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm * * This program is…

Marlin固件配置

文档来源自http://www.geek-workshop.com/thread-33314-1-1.html 1、基本配置基本配置是可选的,主要是给你的固件起个名字,如果你的配置很牛,让大家知道你是谁。据说这个在启动的时候会显示在显示屏中,应为我没有显示屏,所以无法验证。这个修改也很简单,通过搜索找到“S…

MKS MONSTER8 V1.0使用说明书(基于Marlin 2.0.X固件配置Voron 2.4)

广州谦辉信息科技有限公司 (基于Marlin 2.0.x 固件配置 Voron 2.4) 创客基地QQ群:489095605 232237692 邮箱:Huangkaidamakerbase.com.cn 主板购买链接:https://item.taobao.com/item.htm?spma1z10.5-c-s.w4002-23356668283.43.7eec55caLT…

ESP32烧录Marlin固件

安装platformIO 这点很简单,保证你拥有一个能够成功连接外网的环境即可。内网可能不太稳定有可能安装失败。 克隆代码 我这里采用的是fyset_e4的代码,这个代码开源在了https://github.com/FYSETC/FYSETC-E4,作者已经针对marlin固件做了一些配置。 更改…

i3型3D打印机制作详解——Marlin固件中文介绍

关注微信公众号:嵌入式基地 后台回复:3d打印机 获取资料 硬件框架搭建介绍 https://blog.csdn.net/qq_39020934/article/details/80380250 Marlin固件中文介绍 https://download.csdn.net/download/qq_39020934/10401251 …

3D打印机Marlin固件双Z轴设置

3D打印机Marlin固件双Z轴设置 在3D打印机Marlin固件的最新版本2.1.1中,设置双Z轴和老版本有一些改动。记录一下如何在最新版本的Marlin固件中设置双Z轴。 以MKS GEN_L V2.1的主板为例,硬件连接还是和原来一样,第二个Z轴的电动机连接到空闲的…

Marlin 固件配置手动退换料

换料的步骤首先把喷头加热,软化喷嘴里残余的线材,然后反转挤出机,把线材抽出来。最后装入新线材,并挤出余留在喷头里的材料。整个过程用一个命令 M600 就能完成。默认情况下 Marlin 固件并没有开启这个功能,但是可以修…

MKS_SGEN_L V1.0 marlin 固件编译

1.下载 Visual Studio Code 打开Visual Studio Code 安装插件 在应用商店搜索下载安装如下图: 安装完这些还是不行的 还要另外安装python 3.8.8 其他版本python 不行右下角会报错,提示安装python 3.8 python 3.8.8 百度网盘下载链接:https://pan.bai…

3D打印机硬件驱动-马林固件最新版本2.0.X中文注释(1)marlin 2.0.9.2 截至发稿时间2021年12月16日

马林固件最新版本翻译注释 /* Marlin Firmware 马林固件 (c) 2011-2020 MarlinFirmware Portions of Marlin are (c) by their respective authors. 马林部分程序来源于世界各地的开发者 All code complies with GPLv2 and/or GPLv3 所有源码依靠GPLv2 和 GPLv3架构编写…

Marlin固件学习总结(一)

接触过3D打印也有一段时间了,一直没有将学到的知识以文本的形式记录下来。现在也没有太多时间继续玩这个了,因此想慢慢把之前所接触到所学到的知识通过文本的形式记录一下,也分享给那些感兴趣的人。 既然是开篇我们先了解一下marlin固件的结构…

Marlin固件之二:源代码详解与移植

由于需要进行固件定制化,Marlin固件太过于强大和紧凑,我对这个固件进行了裁剪,只剩下主枝干,实现功能的定制和裁剪。以下的代码详解是基于我已经移植在stm32上面的一个程序进行的。

Marlin固件之—:基础入门与测试

一、Marlin的简单介绍 Marlin固件是一个3D打印的开源固件,3D打印固件有许多,Marlin最为健全和强大,当然相对也会复杂一些。使用Gcode控制爱,Gcode是数控机床等工控控制使用范围较广的一种指令协议。在这里介绍一些Marlin的入门经…

Marlin固件介绍

目录 什么是Marlin? 主要特点 Marlin如何工作 打印东西 建模 …

marlin2.0.x 固件相关配置文档说明

主要目的 了解对应参数的作用,以优化3D打印机的打印效果 具体分析 配置文件有两个 Configuration.h 包含硬件核心、语言和控制器的设置,以及最常见的功能和组件的设置,主要配置的地方。 Configuration_adv.h 提供更详细的自定义选项&…

杨辉三角形--2021蓝桥杯Java组

杨辉三角形–2021蓝桥杯Java组 题目描述 下面的图形是著名的杨辉三角形: 如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列:1,1,1,1,2,1,1,3,3,1,1,4,6,4,1,⋯ 给定一个正整数 N,请你输出数列中第一次出现…

JAVA杨辉三角形

杨辉三角形 杨辉三角形(java)首先让我们来实现要求一再来看看要求二对于要求三最后一步给三角形前面加上空格 杨辉三角形(java) 首先让我们来看看杨辉三角形的结构: 要求一:有一个数第二层有两个数要求二:每一层第一个跟最后一个数字都是一**要求三:除了数字一以外其他数字等于…

汉罗塔问题和杨辉三角(java实现)

汉罗塔问题和杨辉三角问题 汉罗塔思路分析:代码: 杨辉三角思路分析代码 汉罗塔 相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺…

杨辉三角形 (蓝桥杯) JAVA

目录 题目描述:暴力破解(四成):二分法破解(满分): 题目描述: 下面的图形是著名的杨辉三角形: 如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到…

【leetcode刷题】34.杨辉三角——Java版

⭐欢迎订阅《leetcode》专栏,每日一题,每天进步⭐ 帕斯卡可能是马可波罗的亲戚,马可波罗回到欧洲后,把杨辉三角告诉了帕斯卡,最后帕斯卡漂亮了抄袭了杨辉三角 ——leetcode此题热评 前言 哈喽,大家好&…