2023/1/15 JS-原型与原型链

news2024/12/22 19:25:07

1 什么是原型

原型是Javascript中的继承的基础,JavaScript的继承就是基于原型的继承。每一个JS对象都可以获得自己的原型,通过原型可以共享函数对象和实例对象之间的属性和方法。
原型的出现,就是为了解决 构造函数 的缺点:
在这里插入图片描述
每一次new一个对象时,都会创建一份render()代码浪费资源。通过原型,我们提供了一个给对象添加函数的方法,不然构造函数只能给对象添加属性,不能合理的添加函数就太 LOW 了。

2 引入原型解决方案

在这里插入图片描述

prototype

每一个函数天生自带一个成员 - prototype,是一个对象空间,即然每一个函数都有,构造函数也是函数,构造函数也有这个对象空间。这个 prototype 对象空间可以由函数名来访问:

function Person() {}
console.log(Person.prototype) // 是一个对象

即然是个对象,那么我们就可以向里面放入一些东西:

function Person() {}
Person.prototype.name = 'prototype'
Person.prototype.sayHi = function () {}

我们发现了一个叫做 prototype 的空间是和函数有关联的,并且可以向里面存储一些东西。
重点: 在函数的 prototype 里面存储的内容,不是给函数使用的,是给函数的每一个实例化对象使用的。
那实例化对象怎么使用能?

__proto__

每一个对象都天生自带一个成员,叫做__proto__,是一个对象空间,即然每一个对象都有,实例化对象也是对象,那么每一个实例化对象也有这个成员。这个 __proto__ 对象空间是给每一个对象使用的:
当你访问一个对象中的成员的时候,如果这个对象自己本身有这个成员,那么就会直接给你结果,如果没有,就会去 __proto__ 这个对象空间里面找,里面有的话就给你结果。

那么这个 __proto__ 又指向哪里呢?
这个对象是由哪个构造函数 new 出来的,那么这个对象的 __proto__ 就指向这个构造函数的 prototype。

function Person() {}
var p1 = new Person()
console.log(p1.__proto__ === Person.prototype) // true

我们发现实例对象的 __proto__ 和所属的构造函数的 prototype 是一个对象空间,我们可以通过构造函数名称来向 prototype 中添加成员。Person.prototype.name = 'prototype'
对象在访问的时候自己没有,可以自动去自己的 __proto__ 中查找

我们可以把函数放在构造函数的 prototype 中,实例化对象访问的时候,自己没有,就会自动去 __proto__ 中找。

function Person() {}Person.prototype.sayHi = function () {
   console.log('hello Person')
}var p1 = new Person()
p1.sayHi()

1 p1 自己没有 sayHi 方法,就会去自己的 __proto__ 中查找 p1.proto 就是 Person.prototype
我们又向 Person.prototype 中添加了 sayHi 方法 所以 p1.sayHi 就可以执行了

到这里,当我们实例化多个对象的时候,每个对象里面都没有方法,都是去所属的构造函数的 protottype 中查找,那么每一个对象使用的函数,其实都是同一个函数。

function Person() {}Person.prototype.sayHi = function () {
   console.log('hello')
}var p1 = new Person()
var p2 = new Person()
​
console.log(p1.sayHi === p2.sayHi)

p1 是 Person 的一个实例
p2 是 Person 的一个实例
也就是说 p1.__proto__p2.__proto__ 指向的都是 Person.prototype
当 p1 去调用 sayHi 方法的时候是去 Person.prototype 中找
当 p2 去调用 sayHi 方法的时候是去 Person.prototype 中找
那么两个实例化对象就是找到的一个方法,也是执行的一个方法。

结论

当我们写构造函数的时候,属性我们直接写在构造函数体内,方法我们写在原型上。

3 原型链

构造函数的 prototype 是一个对象,每一个对象都天生自带一个 __proto__ 属性,那么 构造函数的 prototype 里面的 __proto__ 属性又指向哪里呢?
在这里插入图片描述
每一个对象都有一个自己所属的构造函数,比如: 数组,

// 数组本身也是一个对象
var arr = []
var arr2 = new Array()

以上两种方式都是创造一个数组,我们就说数组所属的构造函数就是 Array。
比如: 函数,

// 函数本身也是一个对象
var fn = function () {}
var fun = new Function()

以上两种方式都是创造一个函数,我们就说函数所属的构造函数就是 Function。

constructor

对象的 __proto__ 里面也有一个成员叫做 constructor,这个属性就是指向当前这个对象所属的构造函数。
在这里插入图片描述

链状结构

当一个对象我们不知道是谁构造的时候,我们把它看成 Object 的实例化对象,也就是说,我们的 构造函数 的 prototype 的__proto__ 指向的是 Object.prototype。

那么 Object.prototype 也是个对象,那么它的 __proto__ 又指向谁呢?
因为 Object 的 js 中的顶级构造函数,我们有一句话叫 万物皆对象,所以 Object.prototype 就到顶了,Object.prototype 的 proto 就是 null。

原型链的访问原则

访问一个对象的成员的时候,自己没有就会去 __proto__ 中找,接下来就是,如果 __proto__ 里面没有就再去 __proto__ 里面找,一直找到 Object.prototype 里面都没有,那么就会返回 undefiend。

对象的赋值

赋值的时候,就是直接给对象自己本身赋值,如果原先有就是修改。原先没有就是添加,不会和 __proto__ 有关系。

总结

所有函数对象都是Function对象的实例,所有对象的原型都指向一个空的Object实例对象(Object对象是一个例外),原型链的尽头是Object对象的原型。
在这里插入图片描述

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

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

相关文章

HTB-Shoppy

HTB-Shoppy信息收集开机提权信息收集 22和80。 能扫描出来的东西很杂,但是admin和login可以重点关注。 访问其中之一,能发现是一个登陆界面。 对其进行简单的sql注入测试。输入admin’or11#会出现504超时,判断可能是因为有sql防御措施所致。…

SpringCloud Netflix复习之Zuul

文章目录写作背景Zuul是什么Zuul的核心功能上手实战SpringCloud中Zuul如何使用自定义过滤器配置全局Fallback降级Zuul请求头Ribbon等其他参数配置过滤敏感请求头参数配置开启Ribbon懒加载和Ribbon超时配置开启Hystrix超时配置(一般不配置没啥用)源码部分请求入口ZuulServlet注入…

C++入门--list

目录 list的介绍: list的构造: 遍历: reverse、sort、unique list的模拟实现: 反向迭代器: list与vector的比较: list的介绍: list是序列容器,允许在序列内的任何位置执行O(…

RocketMQ源码(19)—Broker处理DefaultMQPushConsumer发起的拉取消息请求源码【一万字】

基于RocketMQ release-4.9.3,深入的介绍了Broker处理DefaultMQPushConsumer发起的拉取消息请求源码。 此前我们学习了RocketMQ源码(18)—DefaultMQPushConsumer消费者发起拉取消息请求源码。我们知道consumer在发送了拉取消息请求的时候,请求的Code为PUL…

【 JavaScript编程详解 -1 】什么是JavaScript ?

文章目录简介Java与JavaScript的不同Javascrpt可以做什么JavaScript的构成为什么可以在浏览器中运行如何将 JavaScript 代码添加到网站&#xff1f;方法1- \<script\>标签内嵌JavaScript方法1- \<script\>标签引入外部JavaScript文件方法3- 内联 JavaScript编辑器推…

蛇形矩阵(简单明了的方法)

T112524 【数组2】蛇形矩阵 题目来源 AC代码 #include<stdio.h>int main() {int arr[111][111];int n 0;scanf("%d",&n);int temp 0;int sum 1;while(temp<(2*n-2)){for(int i0;i<n;i){for(int j0;j<n;j){if((ij) temp){if(temp%2 0){arr[…

基于FPGA的时间数字转换(TDC)设计(三)

1.多相位TDC计时测试 以下为多相位TDC计时的测试。图1为多相位TDC计时的测试框图,利用信号发生器,产生两路同相位、具有固定延时的脉冲信号,一路作为Start信号,另外一路作为Stop信号。由于分辨率为312.5ps,因此以312.5ps为步进,对Stop信号进行延时,扫描一个周期,通过UA…

红米 12C earth Fastboot 线刷包 root TWRP 刷入magisk recovery卡刷

红米 12C earth Fastboot 线刷包 root TWRP 刷入magisk recovery卡刷 红米 12C (earth) 国行版 Fastboot 线刷包 & Recovery 卡刷包 ROM 红米 12C earth Fastboot 线刷包 root TWRP 刷入magisk recovery卡刷下载 红米 12C 稳定版 Fastboot 线刷包 要安装国行版 红米 12C F…

对笔试使用《剑指offer》吧(第十天)

跟着博主一起刷题 这里使用的是题库&#xff1a; https://leetcode.cn/problem-list/xb9nqhhg/?page1 目录剑指 Offer 62. 圆圈中最后剩下的数字剑指 Offer 64. 求12…n剑指 Offer 65. 不用加减乘除做加法剑指 Offer 62. 圆圈中最后剩下的数字 剑指 Offer 62. 圆圈中最后剩下的…

【BP靶场portswigger-客户端12】跨站点请求伪造CSRF-12个实验(全)

前言&#xff1a; 介绍&#xff1a; 博主&#xff1a;网络安全领域狂热爱好者&#xff08;承诺在CSDN永久无偿分享文章&#xff09;。 殊荣&#xff1a;CSDN网络安全领域优质创作者&#xff0c;2022年双十一业务安全保卫战-某厂第一名&#xff0c;某厂特邀数字业务安全研究员&…

YOLO家族系列模型的演变:从v1到v8(上)

YOLO V8已经在本月发布了&#xff0c;我们这篇文章的目的是对整个YOLO家族进行比较分析。了解架构的演变可以更好地知道哪些改进提高了性能&#xff0c;并且明确哪些版本是基于那些版本的改进&#xff0c;因为YOLO的版本和变体的命名是目前来说最乱的&#xff0c;希望看完这篇文…

Android 深入系统完全讲解(18)

3 su Root 的相关代码原理 在 Android4.4 的时候&#xff0c;我们经常能够看到 Root Apk&#xff0c;作为发烧友操作这个才算是真的会 Android。那么学习 su 的代码&#xff0c;就是非常有意义的事情。这一节来说下 su 是如何管理权限 的&#xff0c;如何调用授权 Apk&#xf…

撒贝宁搭档某网红,直播带货人气破十万,央视主持人能接私活吗

随着互联网的发展&#xff0c;直播已经司空见惯&#xff0c;直播带货更是成为家常便饭&#xff0c;尤其是那些有了名气的人。就在不久前&#xff0c;央视著名主持人撒贝宁&#xff0c;也开启了自己的直播带货首秀&#xff0c;不得不说央视主持人还是多才多艺。 在很短时间内&am…

SpringBoot 自定义拦截器

SpringBoot 自定义拦截器 目录SpringBoot 自定义拦截器一、自定义拦截器二、编写控制器三、添加拦截器对象&#xff0c;注入到容器的配置类中另一种写法四、最后application运行一、自定义拦截器 创建登录拦截器 com/bjpowernode/springbootinterceptor02/interceptor LoginI…

改进YOLOv7系列:结合丰富的梯度流信息模块,来自YOLOv8的核心模块

&#x1f4a1;统一使用 YOLOv7 代码框架&#xff0c;结合不同模块来构建不同的YOLO目标检测模型。&#x1f31f;本项目包含大量的改进方式,降低改进难度,改进点包含【Backbone特征主干】、【Neck特征融合】、【Head检测头】、【注意力机制】、【IoU损失函数】、【NMS】、【Loss…

【Linux操作系统】进程优先级和进程切换

文章目录一.进程优先级1.三段论谈优先级2.PRI和NI二.进程切换1.进程的四个特性2.上下文数据保护和恢复一.进程优先级 1.三段论谈优先级 什么是优先级&#xff1f;它等同于权限吗&#xff1f; 定义: cpu资源分配的先后顺序&#xff0c;就是指进程的优先权&#xff08;priority…

SpringBoot + MDC 实现全链路调用日志跟踪

写在前面MDC介绍MDC使用MDC 存在的问题解决MDC存在的问题写在前面通过本文将了解到什么是MDC、MDC应用中存在的问题、如何解决存在的问题基于 Spring Boot MyBatis Plus Vue & Element 实现的后台管理系统 用户小程序&#xff0c;支持 RBAC 动态权限、多租户、数据权限、…

Shader踩坑笔记UV操作

一、UV坐标范围0-1 // 坐标范围 0-1&#xff0c;原点在画布左下角 vec2 uv FRAGCOORD.xy / iResolution.xy; 有两个变量 1、FRAGCOORD是godot引擎自带的变量表示纹理坐标 2、iResolution我自定义的变量&#xff0c;输入画布尺寸 使用uniform关键词可以创建自定义变量 比…

戴尔电脑怎么录屏?这6个方法教你轻松录屏

无论您是需要录制屏幕活动以创建在线发布的演示文稿、录制网络研讨会的屏幕以供日后参考&#xff0c;还是出于任何其他原因——如果您使用的是戴尔或类似 PC&#xff0c;您有多种选择。那么&#xff0c;让我们来谈谈如何在戴尔笔记本电脑上进行屏幕记录。 在戴尔笔记本电脑上录…

机器人介绍、应用、前景

机器人介绍、应用、前景1 介绍1.1 定义1.2 作用1.3 发展历程1.4 分类1.5 三大顾虑1.6 前景2 种类工业机器臂协作机械臂工业移动机器人复合机器人扫地机器人服务机器人机器狗人形机器人无人机3 技术3.1 机器人学分类3.2 功能分类3.2.1 感知3.2.2 决策3.2.3 执行AGV减震机构减速机…