JS原型和原型链的理解

原型链图,图中Parent是构造函数,p1是通过Parent实例化出来的一个对象

在这里插入图片描述

前置知识

  1. js中对象和函数的关系,函数其实是对象的一种

  2. 函数、构造函数的区别,任何函数都可以作为构造函数,但是并不能将任意函数叫做构造函数,只有当一个函数通过new关键字调用的时候才可以成为构造函数

    var Parent = function(){}
    var p1 = new Parent();
    
  3. 三个属性__proto__、prototype、 constructor

    • proto、 constructor属性是对象所独有的
    • prototype属性是函数独有的
    • js中函数也是对象的一种,那么函数同样也有属性__proto__、 constructor

prototype属性

在这里插入图片描述

  • prototype 它是函数独有的属性,从图中可以看到它从一个函数指向另一个对象,代表这个对象是这个函数的原型对象,这个对象也是当前函数所创建的实例的原型对象。

  • prototype设计之初就是为了实现继承,让由特定函数创建的所有实例共享属性和方法,也可以说是让某一个构造函数实例化的所有对象可以找到公共的方法和属性。有了prototype我们不需要为每一个实例创建重复的属性方法,而是将属性方法创建在构造函数的原型对象上(prototype)。那些不需要共享的才创建在构造函数中。

  • 当我们想为通过Parent实例化的所有实例添加一个共享的属性时,
    Parent.prototype.name = "我是原型属性,所有实例都可以读取到我";

  • 这就是原型属性,当然你也可以添加原型方法。那问题来了,p1怎么知道他的原型对象上有这个方法呢,往下看

proto属性

在这里插入图片描述

  • __proto__属性是对象(包括函数)独有的。从图中可以看到__proto__属性是从一个对象指向另一个对象,即从一个对象指向该对象的原型对象(也可以理解为父对象)。显然它的含义就是告诉我们一个对象的原型对象是谁。

  • 上面说到,Parent.prototype上添加的属性和方法叫做原型属性和原型方法,该构造函数的实例都可以访问调用。那这个构造函数的原型对象上的属性和方法,怎么能和构造函数的实例联系在一起呢,就是通过__proto__属性。每个对象都有__proto__属性,该属性指向的就是该对象的原型对象
    p1.__proto__ === Parent.prototype; // true

  • __proto__通常称为隐式原型,prototype通常称为显式原型,那我们可以说一个对象的隐式原型指向了该对象的构造函数的显式原型。那么我们在显式原型上定义的属性方法,通过隐式原型传递给了构造函数的实例。这样一来实例就能很容易的访问到构造函数原型上的方法和属性了。
    我们之前也说过__proto__属性是对象(包括函数)独有的,那么Parent.prototype也是对象,那它有隐式原型么?又指向谁?
    Parent.prototype.__proto__ === Object.prototype; //true

  • 可以看到,构造函数的原型对象上的隐式原型对象指向了Object的原型对象。那么Parent的原型对象就继承了Object的原型对象。由此我们可以验证一个结论,万物继承自Object.prototype。这也就是为什么我们可以实例化一个对象,并且可以调用该对象上没有的属性和方法了。如:
    //我们并没有在Parent中定义任何方法属性,但是我们可以调用 p1.toString();//hasOwnProperty 等等的一些方法

  • 我们可以调用很多我们没有定义的方法,这些方法是哪来的呢?现在引出原型链的概念,当我们调用p1.toString()的时候,先在p1对象本身寻找,没有找到则通过p1.__proto__找到了原型对象Parent.prototype,也没有找到,又通过Parent.prototype.__proto__找到了上一层原型对象Object.prototype。在这一层找到了toString方法。返回该方法供p1使用

  • 当然如果找到Object.prototype上也没找到,就在Object.prototype.__proto__中寻找,但是Object.prototype.proto === null所以就返回undefined。这就是为什么当访问对象中一个不存在的属性时,返回undefined了

constructor属性

在这里插入图片描述

  • constructor是对象才有的属性,从图中看到它是从一个对象指向一个函数的。指向的函数就是该对象的构造函数。每个对象都有构造函数,好比我们上面的代码p1就是一个对象,那p1的构造函数是谁呢?我们打印一下。
    console.log(p1.constructor); // ƒ Parent(){}
  • 通过输出结果看到,很显然是Parent函数。我们有说过函数也是对象,那Parent函数是不是也有构造函数呢?显然是有的。再次打印下
    console.log(Parent.constructor); // ƒ Function() { [native code] }
  • 通过输出看到Parent函数的构造函数是Function(),这点也不奇怪,因为我们每次定义函数其实都是调用了new Function(),下面两种效果是一样的
    var fn1 = new Function('msg','alert(msg)');
    function fn1(msg){alert(msg);
    }
    
  • 那么我们再回来看下,再次打印Function.constructor
    console.log(Function.constructor); // ƒ Function() { [native code] }
  • 可以看到Function函数的构造函数就是本身了,那我们也就可以说Function是所有函数的根构造函数。
  • 到这里我们已经对constructor属性有了一个初步的认识,它的作用是从一个对象指向一个函数,这个函数就是该对象的构造函数。通过栗子我们可以看到,p1的constructor属性指向了Parent,那么Parent就是p1的构造函数。同样Parent的constructor属性指向了Function,那么Function就是Parent的构造函数,然后又验证了Function就是根构造函数

参考:https://segmentfault.com/a/1190000021232132 # 巴斯光年

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

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

相关文章

简单的Charles抓包教程

安装Charles 安装地址:https://www.charlesproxy.com/download/ 开关本机抓包 一般我们在抓取手机端内容时需要将Proxy菜单栏下的Windows Proxy取消勾选,禁止charles抓取本机上的请求信息。 注:开启电脑端抓包后,会为电脑添加局…

python之前端css样式(一)

css ID选择器 #c1{color:red;#边框为红色border:1px solid red; } <div id"c2">中国移动</div> 类选择器 .xx{color:blue; } <div class"xx">中国联通</div> 标签选择器 li{color: pink; } <ul><li>北京</li…

CSS动画属性(一)加两实例

keyframes 定义 使用可以创建动画&#xff08;逐步改变从一个CSS样式设定到另一个。)可以设置多次变化发生时使用%/关键字from和to 0&#xff05;是开头动画&#xff0c;100&#xff05;是当动画完成。 为了获得最佳的浏览器支持&#xff0c;始终定义为0&#xff05;和100&…

数据分析 | NumPy

NumPy&#xff0c;全称是 Numerical Python&#xff0c;它是目前 Python 数值计算中最重要的基础模块。NumPy 是针对多维数组的一个科学计算模块&#xff0c;这个模块封装了很多数组类型的常用操作。 使用numpy来创建数组 import numpy as npdata np.array([1, 2, 3]) print…

网络学习:邻居发现协议NDP

目录 前言&#xff1a; 一、报文内容 二、地址解析----NS/NA 目标的被请求组播IP地址 邻居不可达性检测&#xff1a; 重复地址检测 路由器发现 地址自动配置 默认路由器优先级和路由信息发现 重定向 前言&#xff1a; 邻居发现协议NDP&#xff08;Neighbor Discovery…

Linux mount命令教程:如何挂载和管理文件系统(附实例详解和注意事项)

Linux mount命令介绍 mount命令用于将设备上找到的文件系统挂载到以/为根的大树结构&#xff08;Linux文件系统&#xff09;。相反&#xff0c;另一个命令umount可以用来将这些设备从树中分离。 Linux mount命令适用的Linux版本 mount命令在所有主流的Linux发行版中都是可用…

【晴问算法】入门篇—贪心算法—区间不相交问题

题目描述 给定n个开区间&#xff0c;从中选择尽可能多的开区间&#xff0c;使得这些开区间两两没有交集。 输入描述 输出描述 输出一个整数&#xff0c;表示最多选择的开区间个数。 样例1输入 4 1 3 2 4 3 5 6 7 输出 3 解释 最多选择(1,3)、(3,5)、(6,7)三个区间&#xff0c;它…

CSS中水平垂直居中的实现

利用绝对定位&#xff0c;先将元素的左上角通过top:50%和left:50%定位到页面的中心&#xff0c;然后再通过translate来调整元素的中心点到页面的中心。该方法需要考虑浏览器兼容问题。 .parent { position: relative; } .child { position: absolute; left: 50%; …

SAP前台处理:销售业务集成<VA03/VL03N/VLPOD/VF03) 01/02

一、背景&#xff1a; 从销售订单创建VA01>发货过账VL01N >POD确认>VF01开票 这个流程涉及的凭证流及各个节点如何查询上游下游凭证&#xff1b; 二、凭证流&#xff1a; 从销售订单查看销售凭证流 VA03 双击交货单&#xff1a;带出交货单对应行项目及分批次项目…

SpringBoot(文件上传功能,阿里云OSS存储,几种配置文件用法)【详解】

目录 一、新增员工 二、文件上传-技术点 1. 文件上传功能 1.客户端上传文件三要素 2 服务端接收文件 Controller接收文件示例 修改允许上传的文件大小 2. 本地存储文件 3. 阿里云OSS存储&#xff08;这里只写一种&#xff0c;可以用其它的&#xff09; 1.介绍 2.开通…

c# .net6 Task 多线程介绍

c# .net6 Task 多线程介绍 一、Task 启动方式 1. new Task() 直接new Task对象&#xff0c;传入Action委托&#xff0c;该方法不具有参数且不返回值&#xff0c;然后调用Start()即可。 Task task new Task(() >{Console.WriteLine($"01:这里开启了一个线程&#xf…

24计算机考研调剂 | 武汉科技大学

武汉科技大学冶金新技术与功能金属材料研究梯队招收研究生 考研调剂招生信息 学校:武汉科技大学 专业: 工学->治金工程 工学->材料科学与工程 工学->计算机科学与技术 工学->动力工程及工程热物理 工学->机械工程 年级:2024 招生人数:20 招生状态:正在招…

【前端】CSS常见的选择器

CSS&#xff08;层叠样式表&#xff09;提供了多种选择器&#xff0c;用于选择要应用样式的 HTML 元素。在CSS中选择器是一种模式&#xff0c;用于匹配HTML文档中的某些元素并且应用到这些元素上。我们可以通过选择器给特定的元素设置样式。 常见的 CSS 选择器 元素选择器&am…

try~catch语句

用try~catch语句来处理异常&#xff0c;将可能出现的异常操作放在 try部分&#xff0c;将发生异常后的处理放在catch部分。 带finally子语句的try~catch 语法格式 执行机制 ★注意★&#xff1a; try~catch中执行了return → finally子语句仍被执行&#xff1b; try~catch中执…

VScode(8)之阅读大型CC++工程

VScode(8)之阅读大型CC工程(Linux内核)代码 Author&#xff1a;Once Day Date&#xff1a;2023年4月25日/2024年3月17日 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章请查看专栏: VScode开发_Once-Day的博客-CSDN博客 参考文档: 1. 历史包袱 由于上世纪70-80年代的…

【亲测可行】Mac上clion boost库的安装与使用

很多博客上关于boost库的安装与使用都有问题&#xff0c;所以自己写一篇文章来纠正一些错误 这里采用homebrew安装 brew install boost安装好以后boost目录在 /opt/homebrew/Cellar/boost/xxx版本 下&#xff0c;然后可以看到lib&#xff08;库文件&#xff09;和include&…

语音神经科学—04.Speech Computations of the Human Superior Temporal Gyrus

Speech Computations of the Human Superior Temporal Gyrus&#xff08;人类颞上沟的言语计算&#xff09; 专业术语 Superior Temporal Gyrus 颞上沟 phoneme 音素 syllable 音节 speech perception 语音感知 vocal tract 声道 acoustic 声学的 articulatory 发音的 spectro…

【基于Seeed xiao ESP32S3 Sense的自动化HA鱼缸设计】

1.前言 基于Seeed xiao ESP32S3 Sense的自动化HA鱼缸 在当今物联网与智能家居科技日益发达的时代&#xff0c;将先进技术和传统养鱼艺术融合&#xff0c;创造出智能、自动化且极具观赏价值的鱼缸已成为一种创新趋势。SeeedStudio推出的Xiao ESP32-S3 Sense开发板以其卓越的性能…

command failed: npm install --loglevel error --legacy-peer-deps

在使用vue create xxx创建vue3项目的时候报错。 解决方法&#xff0c;之前使用的https://registry.npm.taobao.org 证书过期更换镜像地址即可 操作如下&#xff1a; 1.cd &#xff5e;2.执行rm .npmrc3. sudo npm install -g cnpm --registryhttp://registry.npmmirror.com…

建立人才信息化管理体系,提高企业核心竞争力

很多企业在发展中&#xff0c;都引入了信息化工具系统来提升管理效率。在人力资源管理方面&#xff0c;也有不少信息化系统。通过大量调研发现&#xff0c;在人才管理的初级阶段&#xff0c;企业通过对员工数量统计、员工结构统计、入离职、人才梯队数据、招聘管理数据、培训管…