JS 原型与原型链图解:彻底搞懂的终极指南

前言

 📫 大家好,我是南木元元,热爱技术和分享,欢迎大家交流,一起学习进步!

 🍅 个人主页:南木元元

 在JavaScript中,原型和原型链是非常重要的知识点,只有理解了它们,才能更好地理解js。


目录

构造函数

什么是原型

原型对象和构造函数关系

原型链

显式与隐式原型

__proto__与[[Prototype]]

原型链的概念

Object.getPrototypeOf()方法

hasOwnProperty() 方法

结语


构造函数

创建对象有两种方式:一种是最常见的对象字面量,一种就是通过构造函数来创建。

1.对象字面量

// 对象字面量
let person = {name: "南木元元",age: 22,species: "人类",greet: function() {console.log("Hello!");}
};

2.构造函数

// 构造函数创建对象
function Person(name, age) {this.name = name;this.age = age;this.species = '人类';this.greet = function() {console.log("Hello!");};
}
let person1 = new Person("南木元元", 22);

构造函数和普通函数本质上没什么区别,只不过使用了new关键字创建对象的函数,被叫做了构造函数。构造函数的首字母一般是大写,用以区分普通函数。任何函数只要使用 new 操作符调用就是构造函数,而不使用 new 操作符调用的函数就是普通函数。

// 作为构造函数
let person1 = new Person("南木元元", 22);
person1.greet() //Hello!// 作为函数调用
Person("yuanyuan", 18)
window.greet() //Hello!

什么是原型

 《javascript高级程序设计》中对原型的描述:

每个函数都会创建一个 prototype 属性,这个属性是一个对象,包含应该由特定引用类型的实例共享的属性和方法。实际上,这个对象就是通过调用构造函数创建的对象的原型。使用原型对象的好处是,在它上面定义的属性和方法可以被对象实例共享。

简单来讲,原型就是一个对象,可以实现对象的属性和方法的继承

原型对象和构造函数关系

在JavaScript中,每当定义一个函数数据类型(普通函数、类)时候,都会天生自带一个prototype属性,这个属性指向一个对象,这个对象就是此函数的原型对象。

当函数经过new调用时,这个函数就成为了构造函数,返回一个新的实例对象。

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

每个原型对象上都有个constructor属性,指向它的构造函数。

原型对象有什么用呢?最主要的作用就是用来存放实例对象的公有属性和方法。

在上面例子中,species属性和greet方法对于所有people实例来说都一样,放在构造函数里,那每创建一个实例,就会重复创建一次相同的属性和方法,显得有些浪费。这时候,如果把这些公有的属性和方法放在原型对象里共享,就会好很多。

function Person(name, age) {this.name = name;this.age = age;
}// 定义在原型对象上
Person.prototype.species = '人类';
Person.prototype.greet = function () {console.log("Hello");
}let person1 = new Person('南木元元', 22);
let person2 = new Person('yuanyuan', 18);console.log(person1.species); // 人类 
console.log(person2.species); // 人类person1.greet(); // Hello
person2.greet(); // Hello

为什么实例对象person1和person2中可以访问构造函数Person的原型对象上的方法呢?看上图可以知道,是通过__proto__ 这个属性去访问构造函数的原型对象。

有时候,我们会用person1.constructor查看实例对象的构造函数:

console.log(person1.constructor); // Person()

这个constructor是原型对象上的属性,但实例对象也可以使用,原因就是上面所说的。那如果原型对象上也没有找到想要的属性呢?这就要说到原型链了。

原型链

讲原型链之前,我们需要先了解几个概念。

显式与隐式原型

  • 显式原型就是利用prototype属性查找原型,prototype属性是函数独有的属性。
  • 隐式原型是利用__proto__属性查找原型,这个属性是所有对象都有的属性。

隐式原型__proto__ 的属性值指向它的构造函数的显式原型prototype属性值:

console.log(person1.__proto__ === Person.prototype); // true
console.log(person2.__proto__ === Person.prototype); // true

__proto__与[[Prototype]]

[[Prototype]]用于标识对象的原型。我们来打印一下实例对象person1:

console.log(person1)

你会发现,[[Prototype]]其实就是实例对象person1的原型对象,它的值与person1.__proto__是一样的,通过__proto__可以暴露一个对象内部的原型[[Prototype]]的值。对于使用对象字面量创建的对象,该值是Object.prototype。对于使用数组字面量创建的对象,该值是Array.prototype。对于函数,该值是Function.prototype。

原型链的概念

JavaScript中所有对象都会通过 __proto__ 属性指向自己的原型对象,这个原型对象又会有自己的原型,直到指向Object对象为止,这样就形成了一个链条一样的结构,即原型链。当访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型链上找这个属性,直到找到对应属性或到达原型链的末尾。

  • 原型链的终点是什么?

原型链的终点是null。原型链上的所有原型都是对象,所有的对象最终都是由 Object 构造的。可以在控制台通过Object.prototype.__proto__ 来打印原型链的终点。

Object.getPrototypeOf()方法

__proto__ 属性并不是语言本身的特性,这是各大厂商具体实现时添加的私有属性,虽然目前很多现代浏览器的 JS 引擎中都提供了这个私有属性,但不推荐使用该属性,我们可以使用 Object.getPrototypeOf 方法来获取实例对象的原型,然后再来为原型添加方法/属性。

hasOwnProperty() 方法

使用hasOwnProperty() 方法获得对象非原型链上的属性。

有时候,我们想要判断对象自身中是否具有指定的属性,而不是从原型中继承来的属性,这时可以使用hasOwnProperty() 方法。

function iterate(obj){var res = [];for(var key in obj){if(obj.hasOwnProperty(key)){res.push(key+': '+obj[key]);}}return res;
} 

结语

🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论,支持一下博主~ 

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

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

相关文章

2.2.填充和步幅

我们已经知道,卷积的输出形式取决于输入形式和卷积核的形式。 ​ 此外还有其他因素会影响输出的大小。假设以下情景: 有时,在应用了连续的卷积之后,我们最终得到的输出远小于输入大小。这是由于卷积核的宽度和高度通常大于1所导致…

驱动框架——CMSIS第一部分 RTE驱动框架介绍

一、介绍CMISIS 什么是CMSIS(cortex microcontrol software interface standard一种软件标准接口),官网地址:https://arm-software.github.io/CMSIS_6/latest/General/index.html 包含的core、driver、RTOS、dsp、nn等部分&…

Linux系统编程:自定义协议(序列化和反序列化)

1. 协议 在之前我们谈到,协议就是一种"约定",socket api接口,在读写数据时,都是按照"字符串"的方式来发送接收的,那么我们要传输一些"结构化"数据时怎么办呢?,比如说一个结构…

前端-04-VScode敲击键盘有键入音效,怎么关闭

目录 问题解决办法 问题 今天正在VScode敲项目,不知道是按了什么快捷键还是什么的,敲击键盘有声音,超级烦人啊!!于是我上网查了一下,应该是开启了VScode的键入音效,下面是关闭键入音效的办法。…

分布式服务框架zookeeper+消息队列kafka

一、zookeeper概述 zookeeper是一个分布式服务框架,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:命名服务,状态同步,配置中心,集群管理等。 在分布式环境下,经常需要对应用/服…

云计算数据中心(三)

目录 四、自动化管理(一)自动化管理的特征(二)自动化管理实现阶段(三)Facebook自动化管理 五、容灾备份(一)容灾系统的等级标准(二)容灾备份的关键技术&#…

Flink CDC 同步表至Paimon 写数据流程,write算子和commit算子。

Flink CDC 同步表至Paimon 写数据流程,write算子和commit算子。(未吃透版) 流程图 一般基本flink cdc 任务同步数据至paimon表时包含3个算子,source、write、global commit。 source端一般是flink connector实现的连接源端进行获取数据的过程,本文探究的是 source算子获…

Haproxy服务

目录 一.haproxy介绍 1.主要特点和功能 2.haproxy 调度算法 3.haproxy 与nginx 和lvs的区别 二.安装 haproxy 服务 1. yum安装 2.第三方rpm 安装 3.编译安装haproxy 三.配置文件详解 1.官方地址配置文件官方帮助文档 2.HAProxy 的配置文件haproxy.cfg由两大部分组成&…

Synchronized升级到重量级锁会发生什么?

我们从网上看到很多&#xff0c;升级到重量锁的时候不会降级&#xff0c;再来线程都是重量级锁 今天我们来实验一把真的是这样的吗 1.首选导入Java对象内存布局的工具库&#xff1a; <dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-…

什么是内网穿透?

前言 我们常常会听到“内网穿透”这个术语&#xff0c;但对于很多人来说&#xff0c;它可能还比较陌生。作为一个在网络世界中摸索了一段时间的使用者&#xff0c;我来和大家分享一下我对内网穿透的理解。 目录 一、内网穿透介绍 二、发现 三、特点 四、优势 简单来说&am…

初识godot游戏引擎并安装

简介 Godot是一款自由开源、由社区驱动的2D和3D游戏引擎。游戏开发虽复杂&#xff0c;却蕴含一定的通用规律&#xff0c;正是为了简化这些通用化的工作&#xff0c;游戏引擎应运而生。Godot引擎作为一款功能丰富的跨平台游戏引擎&#xff0c;通过统一的界面支持创建2D和3D游戏。…

Git使用技巧

rebase & merge 先说结论&#xff0c;rebase比较适用于私人分支&#xff0c;可以把主干分支上其他人开发的功能拉到自己的分支上&#xff0c;并且是一条线&#xff1b;merge则主要适用于主分支&#xff0c;可以将其他人的代码合并上去&#xff0c;因为要保留主分支的完整历…

JavaWeb笔记_Cookie

一.会话技术概述 在日常生活中,A和B之间在打电话过程中一连串的你问我答就是一个会话 在BS模型中,会话可以理解为通过浏览器访问服务端的资源,点击超链接可以进行资源的跳转,直到浏览器关闭过程叫做会话 我们使用会话技术可以解决的是整个会话过程中(通过浏览器浏览服务…

css-01-如何实现“文本过长(文本在一行排),超出部分被省略号代替”

目录 需求代码代码解释 需求 最近写一个项目&#xff0c;遇到了一个问题&#xff0c;就是希望实现下面这种文字效果&#xff1a;文字在一行排&#xff0c;超出的部分用省略号代替 代码 <!DOCTYPE html> <html lang"en"><head><meta charset…

【芯片设计- RTL 数字逻辑设计入门 番外篇 12 -- SoC 设计中的 ECO】

请阅读【ARM AMBA AXI 总线 文章专栏导读】 请阅读【芯片设计 RTL 数字逻辑设计扫盲 】 转自&#xff1a;简单了解SoC设计中的ECO — 快乐的芯片工程师 文章目录 ECO 概述Pre-Mask ECO&#xff08;预掩模ECO&#xff09;芯片设计前端与后端的区别 Post-Mask ECO&#xff08;后…

IAR环境下STM32+IAP方案的实现

--基于STM32F103ZET6的UART通讯实现 一、什么是IAP&#xff0c;为什么要IAP IAP即为In Application Programming(在应用中编程)&#xff0c;一般情况下&#xff0c;以STM32F10x系列芯片为主控制器的设备在出厂时就已经使用J-Link仿真器将应用代码烧录了&#xff0c;如果在设备使…

BM34 判断是不是二叉搜索树

1.题目描述 给定一个二叉树根节点&#xff0c;请你判断这棵树是不是二叉搜索树。 二叉搜索树满足每个节点的左子树上的所有节点均小于当前节点且右子树上的所有节点均大于当前节点。 例&#xff1a; 图1 图2 数据范围&#xff1a;节点数量满足 1≤&#x1d45b;≤104 1≤n≤104…

SpringMVC的底层工作原理?

1.用户发送请求至前端控制器DispatcherServlet. 2.DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器 3.HandlerMapping找到具体的处理器(可以根据 xml 配置、注解进行查找&#xff09;&#xff0c;生成处理器及处理器拦截器(如果有则生成)一并返回给DispatcherSe…

AI赋能下的人体摔倒识别技术:深度解析与应用前景

引言 随着人工智能技术的快速发展&#xff0c;AI赋能的解决方案在各行各业中展现出巨大的潜力。特别是在安全监控和健康护理领域&#xff0c;AI技术的应用不仅提高了效率&#xff0c;还极大地提升了安全性。本文将深入探讨思通数科&#xff08;南京&#xff09;信息技术有限公…

【Matlab】RBF径向基神经网络回归预测算法(附代码)

资源下载&#xff1a; https://download.csdn.net/download/vvoennvv/89564332 资源合集&#xff1a; https://download.csdn.net/download/vvoennvv/89564427 目录 【Matlab】BP 神经网络回归预测算法 【Matlab】CNN-LSTM回归预测 卷积神经网络-长短期记忆神经网络组合模型 …