当前位置: 首页 > news >正文

JS 原型和原型链

构造函数

封装是面向对象思想中比较重要的一部分,js 面向对象可以通过构造函数实现的封装。

  • 同样的将变量和函数组合到了一起并能通过 this 实现数据的共享,所不同的是 JS 借助构造函数创建出来的实例对象之间是彼此不影响的

在这里插入图片描述

  • 存在浪费内存的问题,我们希望所有的对象使用同一个函数,这样就比较节省内存,那么我们要怎样做呢?
    在这里插入图片描述

原型

1、prototype

目标:能够利用原型对象实现方法共享

  • 构造函数通过原型分配的函数是所有对象所 共享的

  • JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,所以我们也称为原型对象

  • 这个对象可以挂载函数,对象实例化不会多次创建原型上函数,节约内存

  • 我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法。

  • 构造函数和原型对象中的this 都指向 实例化的对象

  • 注意:这里不可以使用箭头函数,因为箭头函数的this指向上一层

应用

举例【 我们可以把那些不变的方法,直接定义在 prototype 对象上】

 // 我们可以把那些不变的方法,直接定义在 prototype 对象上function Star(uname, age) {this.uname = unamethis.age = age}Star.prototype.sing = function() {console.log(唱歌)}const ldh = new Star('刘德华',55)const zxy = new Star('张学友',58)console.log(ldh.sing === zxy.sing); //true

【构造函数和原型对象中的this 都指向 实例化的对象】

 let thatfunction Star(uname) {that = thisthis.uname = uname}let that2Star.prototype.sing = function() {that2 = thisconsole.log('唱歌');}// 构造函数中的this指向实例化对象const ldh = new Star('刘德华')console.log(that === ldh) // true// 原型对象中的this指向实例化对象ldh.sing()console.log(that2 === ldh) // true

①:给数组扩展求最大值方法和求和方法

比如: 以前学过 const arr = [1,2,3]。arr.reverse() 结果是 [3,2,1]

扩展完毕之后:arr.sum() 返回的结果是 6

  // 求最大值Array.prototype.max = function() {return Math.max(...this) // 展开运算符}Array.prototype.min = function() {return Math.min(...this) // 展开运算符}Array.prototype.sum = function() {return this.reduce( (prev,item)=> prev + item,0)}const arr = new Array(1,2,3) // 数组实例化console.log(arr);console.log(arr.max());console.log(arr.min());console.log(arr.sum());

2、constructor 属性

每个原型对象 prototype 里面都有个constructor 属性(constructor 构造函数)

作用: 该属性指向该原型对象的构造函数, 简单理解,就是指向我的爸爸,我是有爸爸的孩子

在这里插入图片描述

  function Star() {}const ldh = new Star()console.log(Star.prototype.constructor === Star); // true

constructor 的具体作用讲解:

  // 背景需求:我们在原型中添加函数的时候,有可能需要一次性加很多个。function Star2() {}// Star2.prototype.sing = function() {//   console.log('唱歌');// }// Star2.prototype.dance = function() {//   console.log('跳舞');// }console.log(Star2.prototype); // {constructor: ƒ}console.log(Star2.prototype.constructor); //ƒ Star2() {}// 我们想到或许可以用这种方法添加函数:Star2.prototype = {sing: function() {console.log('唱歌');},dance: function() {console.log('跳舞');}}console.log(Star2.prototype); //{sing: ƒ, dance: ƒ}console.log(Star2.prototype.constructor); // ƒ Object() { [native code] }// 但是这种方式出现了问题,这样子的prototype是赋值,不是追加。// 原型失去了原本的constructor
// 解决方法是 加一条constructor: Star 重新指回去。这就是加一条constructor的用处Star2.prototype = {constructor: Star,sing: function() {console.log('唱歌');},dance: function() {console.log('跳舞');}}console.log(Star2.prototype); // {sing: ƒ, dance: ƒ}console.log(Star2.prototype.constructor); // ƒ Star2() {}

3、对象原型

在这里插入图片描述
对象都会有一个属性 __proto__指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数 prototype 原型对象的属性和方法,就是因为对象有 __proto__ 原型的存在。

在这里插入图片描述
__proto__对象原型里面也有一个 constructor属性,指向创建该实例对象的构造函数

  function Star() {}const ldh = new Star()console.log(ldh);// 当前实例对象指向哪个原型对象prototypeconsole.log(ldh.__proto__ === Star.prototype); //true// __proto__对象原型里面也有一个 constructor属性,指向创建该实例对象的构造函数console.log(ldh.__proto__.constructor === Star); //true

构造函数、实例对象、原型的关系

先有构造函数 function Star。用户通过 new Star,创建实例对象。构造函数 Star中 有属性:prototype原型(因为原型是一个对象,所以也叫作原型对象)。

实例对象 new Star()中:

实例对象有一个属性__proto__(对象原型)指向构造函数的 prototype属性(原型对象)。

实例对象的__proto__.constructor指回构造函数 Star。

原型对象prototype中:

constructor指回构造函数 Star。

在这里插入图片描述

  • 练习
  1. prototype是什么?哪里来的?

原型(原型对象)

构造函数都自动有原型

  1. constructor属性在哪里?作用干啥的?

prototype原型和对象原型__proto__里面都有

都指向创建实例对象/原型的构造函数

  1. __proto__属性在哪里?指向谁?

在实例对象里面

指向原型 prototype

在这里插入图片描述

4、原型继承

继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript 中大多是借助原型对象实现继承的特性。

说明:

有女人构造函数Women、男人构造函数Men。

  function Women() {this.eyes = 2this.head = 1}const red = new Women()console.log(red);function Men() {this.eyes = 2this.head = 1}const black = new Men()console.log(black);

因为构造函数中的属性都是一样,所以可以提取一个Person

  const Person = {eyes = 2head = 1}function Women() {}function Man() {}Women.prototype = Person // 通过原型继承Women.prototype.constructor = Women //  补充一个指回Man.prototype = PersonMan.prototype.constructor = Manconst red = new Women()console.log(red);const black = new Man()console.log(black);

通过原型继承

现在想要给女人增加一个生孩子函数 baby

Women.prototype.baby = function { console.log('生孩子')}console.log(red);
console.log(black);

结果发现男人也能生孩子。这是因为两者都继承了同一个对象Person

所以通过 Women.prototype = Person 和 Man.prototype = Person 这种继承是不合理的

所以可以通过构造函数 new对象,而不是const 生成对象

function Person() {this.eyes = 2this.head = 1
}
function Women() {}
function Man() {}Women.prototype = new Person() // 通过原型继承
Women.prototype.constructor = Women //  补充一个指回Man.prototype = new Person()
Man.prototype.constructor = Man//实例验证
Women.prototype.baby = function() {console.log('baby')
}
const red = new Women()
console.log(red);
const black = new Man()
console.log(black);

在这里插入图片描述

5、原型链

__proto__属性的链状结构

基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的结构,我们将原型对象的链状结构关系称为原型链

在这里插入图片描述

  • 举例说明
  // function Object() {// }function Person() {}const ldh = new Person()// 构造函数Person 有prototype(原型)console.log(Person.prototype); console.log(Person.prototype.__proto__ === Object.prototype);  // true//【前提】:每一个构造函数都有原型,每一个对象都有__proto_属性// Person是我们定义的构造函数,构造函数Person 有prototype(原型)// 【Person.prototype】是一个对象,每个对象里面都有一个__PROTO__,// Person.prototype.__PROTO__指向 "构造出【Person.prototype】这个对象的构造函数 的prototype "  // 有一个最大构造函数 Objct,这个构造函数构造出 Person.prototype // 因此,Person.prototype.__PROTO__指向Object 的prototype原型对象(也就是一个对象实例),指向 构造出这个对象的构造函数(function) 的prototype
原型对象

在这里插入图片描述

查找规则

__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线

查找规则如下:

① 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。

② 如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)

③ 如果还没有就查找原型对象的原型(Object的原型对象)

④ 依此类推一直找到 Object 为止(null)

__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线

⑥ 可以使用 instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

const arr = [1,2,3] // arr是对象 相当于 const arr = new Array(1,2,3)
arr.map(function() {// 略
})1、当访问 arr 的方法 map 时,首先查找这个对象自身有没有该属性。
发现没有
2、查找 arr 的原型(也就是 arr.__proto__指向的 prototype 原型对象)
该prototype 原型对象 属于 构造函数 Array的原型,找到了
  • instance of
  const zxy = new Person()console.log(zxy instanceof Person); // zxy 属于 Person 吗 : trueconsole.log(zxy instanceof Object); // zxy 属于 Object 吗 : trueconsole.log(zxy instanceof Array);  // zxy 属于 Array 吗 :  falseconsole.log(Array instanceof Object); // true

小结 原型和原型链

1.原型:函数都有prototype属性,称之为原型,也称为原型对象
原型可以放一些属性和方法,共享给实例对象使用
原型可以做继承
2.原型链:查找一个对象的属性和方法的时候,先在自身找,找不到则沿着__proto__向上查找,我们把__proto__形成的链条关系称原型链

__proto__属性是每一个对象以及函数都有的一个属性。__proto__属性指向的是创建他的构造函数的prototype。原型链就是通过这个属性构件的。

相关文章:

JS 原型和原型链

构造函数 封装是面向对象思想中比较重要的一部分,js 面向对象可以通过构造函数实现的封装。 同样的将变量和函数组合到了一起并能通过 this 实现数据的共享,所不同的是 JS 借助构造函数创建出来的实例对象之间是彼此不影响的 存在浪费内存的问题&#…...

【无标题】图像增强技术:直方图均衡化、拉普拉斯算子、对数变换与伽马变换

图像增强技术:直方图均衡化、拉普拉斯算子、对数变换与伽马变换 在图像处理领域,图像增强是一种关键技术,用于提升图像的视觉效果和质量。本文将介绍四种常用的图像增强方法:直方图均衡化、拉普拉斯算子、对数变换和伽马变换。我…...

自动化专业英语

前言 电子信息、电气工程、自动化专业英语词汇汇总,不定期更新 常用 Asynchronous:异步synchronous:同步notification:通知blade:平面shaft:轴magnetic:磁场的bearing:轴承valve&…...

如何使用 Python 进行数据可视化,比如绘制折线图?

要使用Python进行数据可视化,可以使用matplotlib库来绘制折线图。以下是一个简单的示例代码: 首先,确保已安装matplotlib库。可以使用以下命令安装: pip install matplotlib在Python脚本中导入matplotlib库: import…...

PostgreSQL数据库的事务ID和事务机制

PostgreSQL后续简称PG。PG只读事务不会分配事务ID。为了在共享锁等情况下对事务进行标识,需要一种非持久化的事务ID,即虚拟事务ID,vxid。虚拟事务ID不需要把事务ID持久化到磁盘。因为事务ID是很宝贵的资源,简单的select语句不会申…...

LeetCode 热题 HOT 100 (020/100)【宇宙最简单版】[创作中]

【链表】No. 0142 环形链表 II【中等】👉力扣对应题目指路 希望对你有帮助呀!!💜💜 如有更好理解的思路,欢迎大家留言补充 ~ 一起加油叭 💦 欢迎关注、订阅专栏 【力扣详解】谢谢你的支持&#…...

XML动态sql查询当前时间之前的信息报错

如图&#xff0c;sql语句在数据库里可以正常运行但是再XML文件不可以正常运行&#xff0c;报错。 原因&#xff1a;在XML中小于号"<"是会被默认认定成文一个标签的开始&#xff0c;所以用小于号就会报错。 解决办法&#xff1a; 1.把表达式反过来改成大于号 2…...

EMQX服务器安装MQTT测试

cd /usr/local/develop wget https://www.emqx.com/en/downloads/broker/5.7.1/emqx-5.7.1-el7-amd64.tar.gz mkdir -p emqx && tar -zxvf emqx-5.7.1-el7-amd64.tar.gz -C emqx ./emqx/bin/emqx start 重启 ./emqx/bin/emqx restart http://10.8.0.1:18083/ 账号ad…...

3. 无重复字符的最长子串(滑动窗口)

目录 &#xff1a;题目&#xff1a; 二&#xff1a;代码&#xff1a; 三&#xff1a;结果&#xff1a; 一&#xff1a;题目&#xff1a; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。 二&#xff1a;代码&#xff1a; class Solution { …...

用javaagent和javassist实现Arthas的watch功能

一、被监控的服务 spring-boot-demo 1、 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&q…...

golang 图片转1bit color bmp图片

问题背景 一些打印机需要的都是1bit color bmp图片,但是golang中没有直接的办法,官方image库最低bpp为8,打印机无法使用。 在github上找到了很多资源,都没有直接能转的,突然看到一个老外,可以支持plattered图片转位1bit color bmp图片,然后自己先把图片转位plattered黑…...

Leetcode75-5 反转字符串的元音字母

本质上来说就是反转字符串 一部分需要反转 一部分不动 思路: 1.用String字符串倒序拼接 就是过滤掉不是元音字符 然后把所有的字符&#xff08;非元音的直接复制过来 元音字母直接从反转的字符串里边复制即可&#xff09; 2.看了题解发现自己写的啰嗦了 就是一个双指针问题用…...

static关键字在Java中的作用与用法

static关键字在Java中的作用与用法 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在Java中&#xff0c;static关键字是一个非常重要的概念&#xff0c;用于定义静态成员、方法和内部类。它的使用可…...

50etf期权行权采用什么交割方式 ?

50ETF期权是欧式期&#xff0c;要到期日当天才能行权交制&#xff0c;其交割方式是实物交割买卖双方在到期行权日时需要准备一手交钱&#xff0c;一手收货或是一手交&#xff0c;一手收钱&#xff0c;如果持有期权到达到期日之前&#xff0c;投资者认为行权并不划算&#xff0c…...

ts-node 报错 ERR_UNKNOWN_FILE_EXTENSION

问题 有个monorepo项目&#xff0c;在最外层一次性打包 3 个项目的脚本已经成功实现&#xff0c;如下&#xff1a; "build:test": "cross-env NODE_ENVtest vite build --mode test && esno ./build/script/postBuild.ts", "build:prod"…...

水域救援设备,保护水域安全_鼎跃安全

季作为一年中最炎热的季节&#xff0c;不仅带来了难耐的高温&#xff0c;也悄然间加剧了水域安全问题的严峻性。这一时期&#xff0c;正值学生群体享受悠长暑假的宝贵时光&#xff0c;他们往往倾向于寻找清凉之地以解酷暑&#xff0c;水域因此成为了不少学生的首选之地。然而&a…...

openmetadata本地编译环境搭建

openmetadata本地编译环境搭建 本地环境&#xff1a; Docker 20 or higher Java JDK 17 Antlr 4.9.2 - sudo make install_antlr_cli JQ - brew install jq (osx) apt-get install jq (Ubuntu) Maven 3.5.x or higher - (with Java JDK 11) Python 3.7, 3.8 or 3.9 Node…...

LeetCode Hard|【25. K 个一组翻转链表】

力扣题目链接 首先我们考虑一种很直观的思路&#xff1a; 遍历链表&#xff0c;统计链表长度遍历链表&#xff0c;进行翻转 对于每一组长度为 K 的节点&#xff0c;进行翻转如果剩余节点不足 K 个&#xff0c;则不进行翻转 连接翻转后的子链表 这里我们用的就是只用 O(1) 额外内…...

python爬虫预备知识三-多进程

python实现多进程的方法&#xff1a;fork、multiprocessing模块创建多进程。 os.fork方法 os.fork方法只适合于unix/linux系统&#xff0c;不支持windows系统。 fork方法调用一次会返回两次&#xff0c;原因在于操作系统将当前进程&#xff08;父进程&#xff09;复制出一份…...

【zlm】针对单个设备的音频的编码的设置

目录 结论 原理 测试 结论 为了防止zlm音频配置里设置成opus优先&#xff0c;在国标推流时&#xff0c;调用push时&#xff0c;默认加上codecpcma 如下 https://10.60.100.196:10443/index/api/webrtc?applive&streamtest&typepush&codecpcma 原理 测试 …...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散

前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说&#xff0c;在叠衣服的过程中&#xff0c;我会带着团队对比各种模型、方法、策略&#xff0c;毕竟针对各个场景始终寻找更优的解决方案&#xff0c;是我个人和我司「七月在线」的职责之一 且个人认为&#xff0c…...

微服务通信安全:深入解析mTLS的原理与实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言&#xff1a;微服务时代的通信安全挑战 随着云原生和微服务架构的普及&#xff0c;服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...

ui框架-文件列表展示

ui框架-文件列表展示 介绍 UI框架的文件列表展示组件&#xff0c;可以展示文件夹&#xff0c;支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项&#xff0c;适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...