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

JavaScript 中的原型和原型链

JavaScript 中的原型和原型链也是一个相对较难理解透彻的知识点,下面结合详细例子来进行说明:

一、原型的概念

在 JavaScript 中,每个函数都有一个 prototype 属性,这个属性指向一个对象,这个对象就是所谓的 “原型对象”。当通过构造函数创建一个新的实例对象时,该实例对象会自动拥有一个指向构造函数原型对象的内部属性(在大多数浏览器中可以通过 proto 来访问这个内部属性,虽然它并非标准属性,但方便理解)。
例如:

function Person(name, age) {this.name = name;this.age = age;
}Person.prototype.sayHello = function () {console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
};let john = new Person('John', 30);
john.sayHello(); 
// 输出:Hello, my name is John and I'm 30 years old.

在这个例子中:
首先定义了一个 Person 函数作为构造函数,用来创建 Person 类型的实例。
然后给 Person 函数的 prototype 属性添加了一个 sayHello 方法。
当通过 new Person(‘John’, 30) 创建了 john 这个实例后,john 本身并没有 sayHello 这个方法的定义,但是它可以通过内部的 proto 属性(指向 Person.prototype)找到并调用 sayHello 方法。

二、原型链的形成

当在一个对象上访问某个属性或方法时,如果该对象本身没有这个属性或方法,JavaScript 就会自动沿着它的原型链去查找。原型链就是由对象的 proto 属性连接起来的一系列对象。
继续上面的例子,假设我们有这样一个情况:

function Employee(name, age, department) {Person.call(this, name, age);this.department = department;
}Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;Employee.prototype.sayDepartment = function () {console.log(`I work in the ${this.department} department.`);
};let jane = new Employee('Jane', 25, 'Engineering');
jane.sayHello(); 
// 输出:Hello, my name is Jane and I'm 25 years old.
jane.sayDepartment(); 
// 输出:I work in the Engineering department.

在这个例子中:
首先定义了 Employee 函数作为构造函数来创建 Employee 类型的实例,并且在构造函数内部通过 Person.call(this, name, age) 调用了 Person 构造函数,以便让 Employee 实例继承 Person 实例的 name 和 age 属性。
然后通过 Employee.prototype = Object.create(Person.prototype) 让 Employee 的原型对象继承自 Person 的原型对象,这样 Employee 实例就可以沿着原型链找到 Person 原型对象上的方法(如 sayHello)。同时,重新设置了 Employee.prototype.constructor 为 Employee,以保证构造函数的正确性。
最后给 Employee 原型对象添加了 sayDepartment 方法。
当我们在 jane(Employee 实例)上调用 sayHello 方法时,jane 本身没有 sayHello 方法,它会通过自己的 proto 属性(此时指向 Employee.prototype)找不到,就继续沿着 Employee.prototype 的 proto(因为 Employee.prototype = Object.create(Person.prototype),所以 Employee.prototype.proto 指向 Person.prototype)找到 Person.prototype 上的 sayHello 方法并调用。

三、原型链的查找顺序

为了更清楚地展示原型链的查找顺序,我们再看一个例子:

function Animal() {}
Animal.prototype.eat = function () {console.log('Eating...');
};function Dog() {}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.bark = function () {console.log('Woof!');
};let myDog = new Dog();
myDog.eat(); 
// 输出:Eating...
myDog.bark(); 
// 输出:Woof!// 查看原型链
console.log(myDog.__proto__ === Dog.prototype); 
// 输出:true
console.log(myDog.__proto__.__proto__ === Animal.prototype); 
// 输出:true
console.log(myDog.__proto__.__proto__.__proto__ === Object.prototype); 
// 输出:true
console.log(myDog.__proto__.__proto__.__proto__.__proto__ === null); 
// 输出:true

在这个例子中:
定义了 Animal 函数和其原型对象上的 eat 方法。
定义了 Dog 函数,并让其原型对象继承自 Animal 原型对象,同时在 Dog 原型对象上添加了 bark 方法。
当创建了 myDog 这个 Dog 实例后,在 myDog 上调用 eat 方法时,首先 myDog 本身没有 eat 方法,它会沿着原型链查找。先通过 myDog.proto(指向 Dog.prototype)找不到,再通过 myDog.proto.proto(指向 Animal.prototype)找到并调用 eat 方法。同样,调用 bark 方法时,在 myDog 本身找不到,通过 myDog.proto 就能找到并调用。
从 myDog 的原型链可以看出,查找顺序是先在实例本身查找,然后沿着 proto 指向的对象依次查找,一直到 Object.prototype,最后 Object.prototype.proto 为 null,表示原型链的尽头。

四、原型和原型链的难点

概念的抽象性:原型和原型链涉及到对象、函数、构造函数、原型对象等多个概念的相互关系,理解起来比较抽象。例如,要清楚地区分函数的 prototype 属性和实例对象的 proto 属性,以及它们之间是如何相互作用来实现属性和方法的继承的,这对于初学者来说并不容易。
复杂的继承关系:当涉及到多层继承时,如上面例子中的 Employee 继承自 Person,再加上可能还有更多层的继承关系,要准确把握每个实例沿着原型链查找属性和方法的路径以及如何正确设置继承关系(比如通过 Object.create 等方式),这需要对原型链的机制有深入的理解。
与其他语言的差异:对于有其他编程语言背景的开发者来说,JavaScript 的原型继承方式与基于类的继承(如 Java、C++ 等)有很大的不同。在基于类的继承中,继承关系通常是通过类的定义和关键字(如 extends)来明确规定的,而 JavaScript 是通过原型和原型链这种相对更灵活但也更抽象的方式来实现继承的,所以习惯了类继承的开发者可能会觉得难以适应。
原型和原型链在 JavaScript 中是非常重要的概念,虽然理解起来有一定难度,但掌握它们对于深入理解 JavaScript 的对象系统以及编写高效、灵活的代码至关重要。

相关文章:

JavaScript 中的原型和原型链

JavaScript 中的原型和原型链也是一个相对较难理解透彻的知识点,下面结合详细例子来进行说明: 一、原型的概念 在 JavaScript 中,每个函数都有一个 prototype 属性,这个属性指向一个对象,这个对象就是所谓的 “原型对…...

数组变换(两倍)

数组变换 以最大元素为基准元素,判读其他元素能否通过 x 2 成为最大值! 那么怎么判断呢: max % arr[i] 0arr[i] * 2 ^n max int x 2 ^ n max / arr[i] 3.只需判断 这个 x 是不是 2 的 n 次放就可以了! 判断 是否为 2 的 n 次 …...

GBN协议、SR协议

1、回退N步(Go-Back-N,GBN)协议: 总结: GBN协议的特点: (1)累计确认机制:当发送方收到ACKn时,表明接收方已正确接收序号为n以及序号小于n的所有分组,发送窗…...

三维扫描检测仪3d扫描测量尺寸-自动蓝光测量

在现代工业及生产过程中,精确、高效的尺寸检测是保证产品质量、提升生产效率的关键因素。 红、蓝光测量,以其高精度、高效率和非接触式的特点,在工业及生产中发挥着越来越重要的作用。蓝光测量技术利用蓝色激光光源,通过扫描被测…...

大模型翻译能力评测

1. 背景介绍 随着自然语言处理技术的飞速发展,机器翻译已经成为一个重要的研究领域。近年来,基于大模型的语言模型在机器翻译任务上取得了显著的进展。这些大模型通常具有数亿甚至数千亿的参数,能够更好地理解和生成自然语言。 但是&#xf…...

MySQL隐式转换造成索引失效

一、什么是 MySQL 的隐式转换? MySQL 在执行查询语句时,有时候会自动帮我们进行数据类型的转换,这个过程就是隐式转换。比如说,我们在一个 INT 类型的字段上进行查询,但是传入的查询条件却是字符串类型的值&#xff0c…...

SuperMap Objects组件式GIS开发技术浅析

引言 随着GIS应用领域的扩展,GIS开发工作日显重要。一般地,从平台和模式上划分,GIS二次开发主要有三种实现方式:独立开发、单纯二次开发和集成二次开发。上述的GIS应用开发方式各有利弊,其中集成二次开发既可以充分利…...

多组数输入a+b:JAVA

链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 输入描述: 输入包含多组数据,每组数据输入一行,包含两个整数 输出描述: 对于每组数据输出一行包含一个整数表示两个整数的和 代码: import java.util.Scanner; pu…...

R语言结构方程模型(SEM)在生态学领域中的应用

目录 专题一、R/Rstudio简介及入门 专题二、结构方程模型(SEM)介绍 专题三:R语言SEM分析入门:lavaan VS piecewiseSEM 专题四:SEM全局估计(lavaan)在生态学领域高阶应用 专题五&#xff1…...

架构-微服务-服务调用Dubbo

文章目录 前言一、Dubbo介绍1. 什么是Dubbo 二、实现1. 提供统一业务api2. 提供服务提供者3. 提供服务消费者 前言 服务调用方案--Dubbo‌ 基于 Java 的高性能 RPC分布式服务框架,致力于提供高性能和透明化的 RPC远程服务调用方案,以及SOA服务治理方案。…...

【SpringBoot问题】IDEA中用Service窗口展示所有服务及端口的办法

1、调出Service窗口 打开View→Tool Windows→Service,即可显示。 2、正常情况应该已经出现SpringBoot,如下图请继续第三步 3、配置Service窗口的项目启动类型。微服务一般是Springboot类型。所以这里需要选择一下。 点击最后一个号,点击Ru…...

OpenCV 图像轮廓查找与绘制全攻略:从函数使用到实战应用详解

摘要:本文详细介绍了 OpenCV 中用于查找图像轮廓的 cv2.findContours() 函数以及绘制轮廓的 cv2.drawContours() 函数的使用方法。涵盖 cv2.findContours() 各参数(如 mode 不同取值对应不同轮廓检索模式)及返回值的详细解析,搭配…...

电机驱动MCU介绍

电机驱动MCU是一种专为电机控制设计的微控制器单元,它集成了先进的控制算法和高性能的功率输出能力。 电机驱动MCU采用高性能的处理器核心,具有快速的运算速度和丰富的外设接口。它内置了专业的电机控制算法,包括PID控制、FOC(Fi…...

人工智能学习框架详解及代码使用案例

人工智能学习框架详解及代码使用案例 人工智能(AI)学习框架是构建和训练AI模型的基础工具,它们提供了一组预定义的算法、函数和工具,使得开发者能够更快速、更高效地构建AI应用。本文将深入探讨人工智能学习框架的基本概念、分类、优缺点、选择要素以及实际应用,并通过代…...

修改Textview中第一个字的字体,避免某些机型人民币¥不显示

在 Android 中,系统提供了三种常用的字体类型,分别是: Serif(衬线字体): 这种字体有明显的衬线或笔画末端装饰,通常用于印刷品和书籍,给人一种正式和优雅的感觉。示例:Typeface.SERI…...

彻底理解quadtree四叉树、Octree八叉树 —— 点云的空间划分的标准做法

1.参考文章: (1)https://www.zhihu.com/question/25111128 这里面的第一个回答,有一幅图: 只要理解的四叉树的构建,对于八叉树的构建原理类比方法完全一样:对于二维平面内的随机分布的这些点&…...

Python时间序列优化之道滑动与累积窗口的应用技巧

大家好,在时间序列数据处理中,通常会进行滑动窗口计算(rolling)和累积窗口计算(expanding)等操作,以便分析时间序列的变化趋势或累积特征。Pandas提供的rolling和expanding函数提供了简单、高效的实现方式,特别适用于金融、气象、…...

Buffered 和 BuffWrite

Buffered和BuffWrite是Java IO包中的两个类,用于提高IO操作的效率。 Buffered是一个缓冲区类,可以将一个InputStream或者一个Reader包装起来,提供了一定的缓冲区大小,可以一次读取多个字节或字符,减少了读取的次数&am…...

【娱乐项目】基于cnchar库与JavaScript的汉字查询工具

Demo介绍 利用了 cnchar 库来进行汉字相关的信息查询,并展示了汉字的拼音、笔画数、笔画顺序、笔画动画等信息用户输入一个汉字后,点击查询按钮,页面会展示该汉字的拼音、笔画数、笔画顺序,并绘制相应的笔画动画和测试图案 cnchar…...

泷羽sec-蓝队基础之网络七层杀伤链 (下)学习笔记

声明! 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&a…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...

数据库分批入库

今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...