javascript中原型链(__proto__)与原型(prototype)

JavaScript中原型链(proto)与原型(prototype)

在JavaScript中,理解原型链(__proto__)和原型(prototype)对于深入掌握面向对象编程至关重要。本文将通过示例代码,详细解析__proto__prototype之间的关系,以及它们在对象和构造函数之间的作用。

一、基本概念

1. 构造函数与实例对象

  • 构造函数:在JavaScript中,函数可以作为构造函数使用,通过new关键字创建实例对象。
  • 实例对象:由构造函数创建的对象,继承了构造函数的属性和方法。

2. 原型(prototype

  • prototype:每个函数(包括构造函数)都有一个prototype属性,指向一个对象,这个对象被称为原型对象。
  • 原型对象:存储共享的属性和方法,供所有实例对象访问。

3. 原型链(__proto__

  • proto:每个对象都有一个__proto__属性,指向创建该对象的构造函数的原型对象。
  • 原型链:通过__proto__属性,将对象、构造函数和原型对象连接起来,形成一个链式结构。

二、示例代码解析

下面通过一段示例代码,逐步解析__proto__prototype之间的关系。

function Person(name, age){this.name = name;this.age = age;
}const person = new Person('Tom', 18);// 构造函数的prototype就是实例对象的__proto__
console.log(Person.prototype === person.__proto__); // true// 实例对象的constructor指向构造函数
console.log(person.constructor === Person); // true// 实例对象的__proto__对象上的constructor指向的又是Person构造函数
console.log(person.__proto__.constructor === Person); // true// 实例对象的__proto__对象的__proto__指向的是Object构造函数的prototype
console.log(person.__proto__.__proto__ === Object.prototype); // true// 每一个构造函数也是一个对象,所以也都有__proto__属性,指向的是Function构造函数的prototype
console.log(Person.__proto__ === Function.prototype); // true// Function构造函数的prototype的constructor指向Function构造函数
console.log(Function.prototype.constructor === Function); // true// Function的prototype的__proto__指向Object的prototype
console.log(Function.prototype.__proto__ === Object.prototype); // true// 因为所有构造函数的__proto__都是指向Function的prototype,所以Function构造函数的prototype和__proto__是相等的
console.log(Function.__proto__ === Function.prototype); // true

1. 实例对象与构造函数的关系

console.log(Person.prototype === person.__proto__); // true
  • 解析
    • Person.prototype是构造函数Person的原型对象。
    • person.__proto__是实例对象person的原型,指向Person.prototype
    • 因此,Person.prototype === person.__proto__返回true

2. 实例对象的constructor属性

console.log(person.constructor === Person); // true
  • 解析
    • 实例对象personconstructor属性指向其构造函数Person
    • 因此,person.constructor === Person返回true

3. 原型对象的constructor属性

console.log(person.__proto__.constructor === Person); // true
  • 解析
    • person.__proto__Person.prototype,它有一个constructor属性,指向构造函数Person
    • 因此,person.__proto__.constructor === Person返回true

4. 原型链向上查找

console.log(person.__proto__.__proto__ === Object.prototype); // true
  • 解析
    • person.__proto__Person.prototype
    • Person.prototype.__proto__指向Object.prototype
    • 因此,person.__proto__.__proto__ === Object.prototype返回true

5. 构造函数也是对象

console.log(Person.__proto__ === Function.prototype); // true
  • 解析
    • 构造函数Person本身是一个函数对象,所以它的__proto__属性指向Function.prototype
    • 因此,Person.__proto__ === Function.prototype返回true

6. Function构造函数的关系

console.log(Function.prototype.constructor === Function); // true
console.log(Function.prototype.__proto__ === Object.prototype); // true
console.log(Function.__proto__ === Function.prototype); // true
  • 解析
    • Function.prototypeFunction构造函数的原型对象。
    • Function.prototype.constructor指向Function自身。
    • Function.prototype.__proto__指向Object.prototype,因为函数也是对象。
    • Function.__proto__指向Function.prototype,因为Function也是函数,是自己的构造函数。
    • 因此,上述三个console.log均返回true

三、原型链查找属性的过程

console.log(person.__proto__); // Person {}
console.log(person.__proto__.__proto__); // Object {}
console.log(person.__proto__.__proto__.__proto__); // null
  • 解析
    • person.__proto__Person.prototype
    • person.__proto__.__proto__Object.prototype
    • person.__proto__.__proto__.__proto__null,表示原型链的顶端。

四、总结

1. 关于__proto__prototype

  • __proto__

    • 是每个对象都有的内置属性,指向其构造函数的原型对象。
    • 用于实现对象的原型链,在查找属性时,如果对象自身没有,会沿着__proto__向上查找。
  • prototype

    • 是构造函数的属性,指向原型对象。
    • 原型对象上定义的方法和属性会被构造函数的所有实例共享。

2. 关于构造函数和实例对象

  • 实例对象的__proto__

    • 指向构造函数的prototype属性。
  • 实例对象的constructor

    • 通过__proto__找到原型对象,原型对象的constructor指向构造函数。
  • 构造函数的__proto__

    • 因为构造函数本身是一个函数对象,所以它的__proto__指向Function.prototype

3. 关于原型链的查找过程

  • 当访问对象的属性时,JavaScript引擎会先查找对象自身的属性。
  • 如果找不到,会沿着__proto__属性指向的原型对象继续查找。
  • 这个过程会一直持续,直到找到属性或到达原型链的顶端(null)。

4. 关于Function和Object

  • Function构造函数

    • 是所有函数的构造函数,包括Function自身。
    • Function.__proto__ === Function.prototype,因为Function是一个函数,其__proto__指向Function.prototype
  • Object构造函数

    • 是所有对象的构造函数,包括Function.prototype
    • Function.prototype.__proto__ === Object.prototype

五、深入思考

  • 为什么Function.__proto__ === Function.prototype

    • 因为Function是所有函数的构造函数,包括它自己。Function作为一个函数对象,其__proto__指向Function.prototype
  • 为什么Object.__proto__ === Function.prototype

    • Object是一个函数(构造函数),所以其__proto__指向Function.prototype
  • 为什么Function.prototype.__proto__ === Object.prototype

    • Function.prototype是一个对象,因此其__proto__指向Object.prototype

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

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

相关文章

uibot发送邮件:自动化邮件发送教程详解!

uibot发送邮件的操作指南?uibot发送邮件的两种方式? 在现代办公环境中,自动化流程的引入极大地提高了工作效率。uibot发送邮件功能成为了许多企业和个人实现邮件自动化发送的首选工具。AokSend将详细介绍如何使用uibot发送邮件。 uibot发送…

使用Pytorch写简单线性回归

文章目录 Pytorch一、Pytorch 介绍二、概念三、应用于简单线性回归 1.代码框架2.引用3.继续模型(1)要定义一个模型,需要继承nn.Module:(2)如果函数的参数不具体指定,那么就需要在__init__函数中添加未指定的变量: 2.定义数据3.实例…

IP地址类型选择指南:动态IP、静态IP还是数据中心IP?

你是否曾经困惑于如何选择最适合业务需求的IP地址类型?面对动态IP、静态IP和数据中心IP这三种选择,你是否了解它们各自对你的跨境在线业务可能产生的深远影响? 在跨境电商领域,选择合适的IP类型对于业务的成功至关重要。动态IP、…

gitee开源商城diygw-mall

DIYGW可视化开源商城系统。所的界面布局显示都通过低代码可视化开发工具生成源码实现。支持集成微信小程序支付。 DIYGW可视化开源商城系统是一款基于thinkphp8 framework、 element plus admin、uniapp开发而成的前后端分离系统。 开源商城项目源码地址:diygw商城…

Java中String类的常见操作Api

目录 String类的常见操作 1).int indexOf (char 字符) 2).int lastIndexOf(char 字符) 3).int indexOf(String 字符串) 4).int lastIndexOf(String 字符串) 5).char charAt(int 索引) 6).Boolean endWith(String 字符串) 7).int length() 8).boolean equals(T 比较对象) 9).b…

区块链积分系统:重塑支付安全与商业创新的未来

在当今社会,数字化浪潮席卷全球,支付安全与风险管理议题日益凸显。随着交易频次与规模的不断扩大,传统支付体系正面临前所未有的效率、合规性和安全挑战。 区块链技术,凭借其去中心化、高透明度以及数据不可篡改的特性&#xff0c…

SSH 公钥认证:从gitlab clone项目repo到本地

这篇文章的分割线以下文字内容由 ChatGPT 生成(我稍微做了一些文字上的调整和截图的补充),我review并实践后觉得内容没有什么问题,由此和大家分享。 假如你想通过 git clone git10.12.5.19:your_project.git 命令将 git 服务器上…

简单的maven nexus私服学习

简单的maven nexus私服学习 1.需求 我们现在使用的maven私服是之前同事搭建的,是在公司的一台windows电脑上面,如果出问题会比较难搞,所以现在想将私服迁移到我们公司的测试服务器上,此处简单了解一下私服的一些配置记录一下&am…

多线程(二):Thread类常见的属性和方法

目录 1、run & start 2、Thread类常见的属性和方法 2.1 构造方法 2.2 属性 3、后台进程 & 前台进程 4、setDaemon 5、isAlive 6、终止一个线程 6.1 变量捕获 6.2 currentThread & isInterrupted & interrupt 1、run & start 在多线程&#xff08…

Java面试宝典-Java集合01

Java面试宝典-Java集合01 目录 Java面试宝典-Java集合01 1、Java中常用的集合有哪些? 2、Collection 和 Collections 有什么区别? 3、为什么集合类没有实现 Cloneable 和 Serializable 接口? 4、数组和集合有什么本质区别? 5、数组…

Java | Leetcode Java题解之第470题用Rand7()实现Rand10()

题目&#xff1a; 题解&#xff1a; class Solution extends SolBase {public int rand10() {int a, b, idx;while (true) {a rand7();b rand7();idx b (a - 1) * 7;if (idx < 40) {return 1 (idx - 1) % 10;}a idx - 40;b rand7();// get uniform dist from 1 - 63…

蓝桥杯【物联网】零基础到国奖之路:十七. 扩展模块之单路ADC和NE555

蓝桥杯【物联网】零基础到国奖之路:十七. 扩展模块之单路ADC和NE555 第一节 硬件解读第二节 CubeMx配置第三节 代码1&#xff0c;脉冲部分代码2&#xff0c;ADC部分代码![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/57531a4ee76d46daa227ae0a52993191.png) 第一节 …

React技术在Meta Connect 2024大会

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

熵权法计算评价指标权重——使用Excel VBA实现

[ 熵权法 ] 信息是系统有序程度的一个度量&#xff0c;熵是系统无序程度的一个度量&#xff1b;根据信息熵的定义&#xff0c;对于某项指标&#xff0c;可以用熵值来判断某个指标的离散程度&#xff0c;其信息熵值越小&#xff0c;指标的离散程度越大&#xff0c; 该指标对综合…

数据库——表格之间的关系(表格之间的连接和处理)

数据库表格之间经常存在各种关系&#xff1a; 一对一、一对多、多对多 1.一对一 —— 丈夫表&#xff0c;妻子表为例 连接方式一&#xff1a;合并为一张表 这种方式对于一对一来说最优 连接方式二&#xff1a;在其中一张表内加入一个外键&#xff0c;连接另一张表 连…

ARM base instruction -- sdiv

有符号除法运算 Signed Divide divides a signed integer register value by another signed integer register value, and writes the result to the destination register. The condition flags are not affected. 将一个有符号整数寄存器值除以另一个有符号整数寄存器值&am…

Java中的switch分支结构

switch分支结构 switch分支结构1.基本语法2.说明3.流程图4.案例5.注意事项6.练习7.switch和if的比较 switch分支结构 1.基本语法 switch&#xff08;表达式&#xff09;{case 常量1: //当...语句块1;break;case 常量2: 语句块2;break;...case 常量n: 语句块n;break;defaul…

路径跟踪之导航向量场——二维导航向量场

今天带来一期轨迹跟踪算法的讲解&#xff0c;首先讲解二维平面中的导航向量场[1]。该方法具有轻量化、计算简便、收敛性强等多项优点。该方法根据期望的轨迹函数&#xff0c;计算全局位置的期望飞行向量&#xff0c;将期望飞行向量转为偏光角&#xff0c;输入底层控制器&#x…

prometheus client_java实现进程的CPU、内存、IO、流量的可观测

文章目录 1、获取进程信息的方法1.1、通过读取/proc目录获取进程相关信息1.2、通过Linux命令获取进程信息1.2.1、top&#xff08;CPU/内存&#xff09;命令1.2.2、iotop&#xff08;磁盘IO&#xff09;命令1.2.3、nethogs&#xff08;流量&#xff09;命令 2、使用prometheus c…

AAA Mysql与redis的主从复制原理

一 &#xff1a;Mysql主从复制 重要的两个日志文件&#xff1a;bin log 和 relay log bin log&#xff1a;二进制日志&#xff08;binnary log&#xff09;以事件形式记录了对MySQL数据库执行更改的所有操作。 relay log&#xff1a;用来保存从节点I/O线程接受的bin log日志…