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

深入解析 JavaScript 原型与原型链:从原理到应用

原型原型链是 JavaScript 中实现对象继承和属性查找的核心机制。为了更深入地理解它们,我们需要从底层原理、实现机制以及实际应用等多个角度进行分析。


1. 原型(Prototype)

1.1 什么是原型?

  • 每个 JavaScript 对象(除 null 外)都有一个内部属性 [[Prototype]],指向它的原型对象。
  • 原型对象也是一个普通对象,它包含可以被其他对象共享的属性和方法。
  • 通过 __proto__(非标准,但广泛支持)或 Object.getPrototypeOf() 可以访问对象的原型。

1.2 构造函数与原型

  • 每个函数(构造函数)都有一个 prototype 属性,指向一个对象,这个对象是该构造函数实例的原型。
  • 当使用 new 关键字创建实例时,实例的 [[Prototype]] 会指向构造函数的 prototype 对象。
function Person(name) {this.name = name;
}// 在构造函数的原型上添加方法
Person.prototype.sayHello = function() {console.log(`Hello, my name is ${this.name}`);
};const person1 = new Person('Alice');
person1.sayHello(); // 输出: Hello, my name is Alice
  • 在上面的例子中:
    • Person.prototypeperson1 的原型对象。
    • person1.__proto__ 指向 Person.prototype

2. 原型链(Prototype Chain)

2.1 什么是原型链?

  • 原型链是由对象的 [[Prototype]] 连接起来的链式结构。
  • 当访问对象的属性或方法时,如果对象本身没有该属性,JavaScript 会沿着原型链向上查找,直到找到该属性或到达原型链的顶端(null)。

2.2 原型链的顶端

  • 所有对象的原型链最终都会指向 Object.prototype,而 Object.prototype[[Prototype]]null
  • 如果在整个原型链中都找不到属性,则返回 undefined
console.log(person1.toString()); // 输出: [object Object]
  • 在上面的例子中:
    • person1 本身没有 toString 方法。
    • JavaScript 引擎会沿着原型链查找:
      1. person1 -> 没有 toString
      2. person1.__proto__(即 Person.prototype) -> 没有 toString
      3. Person.prototype.__proto__(即 Object.prototype) -> 找到 toString,调用它。

3. 原型链的深度分析

3.1 原型链的构建

  • 原型链是通过 [[Prototype]] 连接起来的。
  • 当我们创建一个对象时,它的 [[Prototype]] 会指向某个原型对象。
const obj = {};
console.log(obj.__proto__ === Object.prototype); // true
  • 如果我们手动修改 [[Prototype]],可以构建自定义的原型链。
const parent = { name: 'Parent' };
const child = Object.create(parent); // child.__proto__ 指向 parent
console.log(child.name); // 输出: Parent

3.2 原型链的查找机制

  • 当访问对象的属性时,JavaScript 引擎会按照以下步骤查找:
    1. 检查对象自身是否有该属性。
    2. 如果没有,沿着 [[Prototype]] 向上查找。
    3. 重复这个过程,直到找到属性或到达 null
const grandparent = { familyName: 'Smith' };
const parent = Object.create(grandparent);
const child = Object.create(parent);console.log(child.familyName); // 输出: Smith
  • 在上面的例子中:
    • child 自身没有 familyName
    • child.__proto__(即 parent)也没有 familyName
    • parent.__proto__(即 grandparent)有 familyName,返回 Smith

4. 原型链与继承

4.1 基于原型的继承

  • JavaScript 通过原型链实现继承。
  • 子类的原型对象指向父类的实例,从而继承父类的属性和方法。
function Person(name) {this.name = name;
}Person.prototype.sayHello = function() {console.log(`Hello, my name is ${this.name}`);
};function Student(name, grade) {Person.call(this, name); // 调用父类构造函数this.grade = grade;
}// 继承父类原型
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student; // 修复构造函数指向const student1 = new Student('Bob', 10);
student1.sayHello(); // 输出: Hello, my name is Bob
  • 在上面的例子中:
    • Student.prototype 的原型指向 Person.prototype
    • student1 可以访问 Person.prototype 上的方法。

4.2 原型链的局限性

  • 原型链继承是单向的,子类可以访问父类的属性和方法,但父类不能访问子类的属性和方法。
  • 如果原型链过长,属性查找的性能会受到影响。

5. 原型链的实际应用

5.1 共享方法

  • 将方法定义在原型上,可以避免每个实例都创建一份方法的副本,节省内存。
function Person(name) {this.name = name;
}Person.prototype.sayHello = function() {console.log(`Hello, my name is ${this.name}`);
};const person1 = new Person('Alice');
const person2 = new Person('Bob');// person1 和 person2 共享同一个 sayHello 方法
console.log(person1.sayHello === person2.sayHello); // true

5.2 扩展内置对象

  • 可以通过修改内置对象的原型来扩展其功能。
Array.prototype.last = function() {return this[this.length - 1];
};const arr = [1, 2, 3];
console.log(arr.last()); // 输出: 3

6. 总结

  • 原型:每个对象都有一个 [[Prototype]],指向它的原型对象。
  • 原型链:通过 [[Prototype]] 连接起来的链式结构,用于属性查找。
  • 继承:通过原型链实现对象之间的继承。
  • 性能:原型链过长会影响查找性能,需谨慎设计。

理解原型和原型链是掌握 JavaScript 面向对象编程的关键,也是深入理解 JavaScript 运行机制的基础。

相关文章:

深入解析 JavaScript 原型与原型链:从原理到应用

原型和原型链是 JavaScript 中实现对象继承和属性查找的核心机制。为了更深入地理解它们,我们需要从底层原理、实现机制以及实际应用等多个角度进行分析。 1. 原型(Prototype) 1.1 什么是原型? 每个 JavaScript 对象&#xff08…...

关于AI数据分析可行性的初步评估

一、结论:可在部分环节嵌入,无法直接处理大量数据 1.非本地部署的AI应用处理非机密文件没问题,内部文件要注意数据安全风险。 2.AI(指高规格大模型)十分适合探索性研究分析,对复杂报告无法全流程执行&…...

回归预测 | Matlab实现GWO-BP-Adaboost基于灰狼算法优化BP神经网络结合Adaboost思想的回归预测

回归预测 | Matlab实现GWO-BP-Adaboost基于灰狼算法优化BP神经网络结合Adaboost思想的回归预测 目录 回归预测 | Matlab实现GWO-BP-Adaboost基于灰狼算法优化BP神经网络结合Adaboost思想的回归预测回归效果基本介绍GWO-BP-Adaboost:基于灰狼算法优化BP神经网络结合Adaboost思想…...

ARM Cortex-M 内存映射详解:如何基于寄存器直接读写 寄存器映射方式编码程序 直接操作硬件寄存器来控制 MCU

ARM Cortex-M 的系统映射空间 ​ 在 STM32 等 ARM Cortex-M 系列 MCU 中,内存地址空间按照 存储功能 进行了严格划分,包括 Flash(程序存储)、RAM(数据存储)、外设寄存器(GPIO、UART、SPI 等&am…...

深度学习实战车辆目标跟踪与计数

本文采用YOLOv8作为核心算法框架,结合PyQt5构建用户界面,使用Python3进行开发。YOLOv8以其高效的实时检测能力,在多个目标检测任务中展现出卓越性能。本研究针对车辆目标数据集进行训练和优化,该数据集包含丰富的车辆目标图像样本…...

django中视图作用和视图功能 以及用法

在 Django REST Framework(DRF)中,视图(View)是处理 HTTP 请求并返回响应的核心组件。DRF 提供了多种视图类,适用于不同的场景和需求。以下是 DRF 中常见的视图类及其作用、使用方法的详细说明: 一、DRF 视图的分类 DRF 的视图可以分为以下几类: 基于函数的视图(Func…...

【每日学点HarmonyOS Next知识】输入框自动获取焦点、JS桥实现方式、Popup设置全屏蒙版、鼠标事件适配、Web跨域

1、HarmonyOS TextInput或TextArea如何自动获取焦点? 可以使用 focusControl.requestFocus 对需要获取焦点的组件设置焦点,具体可以参考文档: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attribut…...

【学习思维模型】

学习思维模型 一、理解类模型二、记忆类模型三、解决问题类模型四、结构化学习模型五、效率与习惯类模型六、高阶思维模型七、实践建议八、新增学习思维模型**1. 波利亚问题解决四步法****2. 主动回忆(Active Recall)****3. 鱼骨图(因果图/Ishikawa Diagram)****4. MECE原则…...

MyBatis-Plus分页控件使用及使用过程发现的一个坑

最近维护一个旧项目的时候,出现了一个BUG,经排查后发现是Mybatis-plus分页控件使用的时候需要注意的一个问题,故在本地使用MybatisPlus模拟出现了一下这个问题。 首先,先说一下MyBatis-Plus的使用: 1)引入…...

STM32的APB1和APB2的区别

STM32微控制器中的APB1和APB2的区别 STM32微控制器中的APB1和APB2是两种不同的外设总线,主要区别在于时钟速度、连接的外设以及用途。以下是它们的详细对比: 1. 时钟速度 APB1 (Advanced Peripheral Bus 1): 低速总线,时钟频率通常为系统时钟…...

JS一些小知识点

一、|| 运算符 plain this.ctx.body { type: type || 0, // ||在此处用法用于默认值填充,判断是否传参或该值是否存在,如果不存在就使用||后买你的值作为默认值 code: code || 0, msg: msg || SUCCESS, data: data || {}, ...others }; 二、trim() 方…...

手写Tomcat:实现基本功能

首先,Tomcat是一个软件,所有的项目都能在Tomcat上加载运行,Tomcat最核心的就是Servlet集合,本身就是HashMap。Tomcat需要支持Servlet,所以有servlet底层的资源:HttpServlet抽象类、HttpRequest和HttpRespon…...

C#变量与变量作用域详解

一、变量基础 1. ‌声明与初始化‌ 声明语法‌&#xff1a;<数据类型> <变量名>&#xff08;如 int age; string name&#xff09;‌初始化要求‌&#xff1a; 1、 类或结构体中的字段变量&#xff08;全局变量&#xff09;‌无需显式初始化‌&#xff0c;默认值…...

SV学习笔记——数组、队列

一、定宽数组 定宽数组是静态变量&#xff0c;编译时便已经确定其大小&#xff0c;其可以分为压缩定宽数组和非压缩定宽数组:压缩数组是定义在类型后面&#xff0c;名字前面;非压缩数组定义在名字后面。Bit [7:0][3:0] name; bit[7:0] name [3:0]; 1.1定宽数组声明 数组的声…...

API调试工具的无解困境:白名单、动态IP与平台设计问题

引言 你是否曾经在开发中遇到过这样的尴尬情形&#xff1a;你打开了平台的API调试工具&#xff0c;准备一番操作&#xff0c;结果却发现根本无法连接到平台&#xff1f;别急&#xff0c;问题出在调试工具本身。今天我们要吐槽的就是那些神奇的开放平台API调试工具&#xff0c;…...

Git清理本地残留的、但已经在服务器上被删除的分支

要筛选出已经被服务器删除的本地分支&#xff0c;并在本地删除这些分支&#xff0c;可以按照以下步骤进行操作&#xff1a; 步骤 1: 获取远程分支信息&#xff0c;确保本地的远程分支信息是最新的&#xff1a; git fetch -p步骤 2: 列出本地分支和远程分支&#xff1a; git …...

HTTPS实现内容加密的逻辑

加密过程 使用非对称加密&#xff0c;网站生成公钥和私钥浏览器获取到网站公钥&#xff08;通过验证和解析CA证书&#xff09;&#xff0c;随即生成一串字符串&#xff0c;然后使用公钥加密&#xff0c;发送给网站。网站用私钥将加密内容解析&#xff0c;然后使用这串字符串对…...

使用vue3.0+electron搭建桌面应用并打包exe

使用vue3.0electron搭建桌面应用并打包exe_如何使用electron将vue3vite开发完的项目打包成exe应用程序-CSDN博客...

JSAR 基础 1.2.1 基础概念_空间小程序

JSAR 基础 1.2.1 基础概念_空间小程序 空间空间自由度可嵌入空间空间小程序 最新的技术进展表明&#xff0c;官网之前的文档准备废除了&#xff0c;基于xsml的开发将退出历史舞台&#xff0c;three.js和普通web结合的技术将成为主导。所以后续学习请移步three.js学习路径&#…...

mysql练习

创建数据库db_ck&#xff0c;再创建表t_hero&#xff0c;将四大名著中的主要人物都插入这个表中&#xff0c;将实现过程中sql提交上上来 1、创建数据库db_ck mysql> create database db_ck; 2、创建表t_hero mysql> use db_ck Database changed mysql> create table …...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...