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

news2024/11/14 0:06:20

前言

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

 🍅 个人主页:南木元元

 在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.coloradmin.cn/o/1939838.html

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

相关文章

Express+mysql单表分页条件查询

声明(自己还没测试过,只提供大概逻辑,什么多表连接查询可以在原基础上添加) class /*** param connection Express的mysql数据库链接对象* current 当前页* pageSize 一页显示行数* where [{key:id,operator:,value15}], key查询…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 卢小姐的生日礼物(200分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题目在线…

pg_restore导入错误的解决思路

背景 开发使用postgresql 数据库,当需要部署时,通过pg_dump导出,通过pg_restore导入,发现导入遇到错误,很多表没有导入。部分报错截图如下: 排查问题 开发中用到了postgresql插件postgis里的地理类型&am…

ORBSLAM3 ORB_SLAM3 Ubuntu20.04 ROS Noetic 虚拟机镜像 下载

下图是build.sh 和 build_ros.sh编译结果截图: slam数据集测试视频: orbslam3 ubuntu20.04 test 下载地址: 链接:https://pan.baidu.com/s/1nre0Y9vig5QXIGU52qCLbQ?pwd9rbi 提取码:9rbi

什么是裸机管理程序?

在这个旨在使最终用户体验尽可能无缝的快节奏环境中,企业不断扩展其网络以处理增加的负载,为了应对可扩展性问题并增强其设备的最佳性能,网络管理员开始使用虚拟化技术。 通过使用管理程序虚拟化网络,网络管理员可以实现灵活、可…

C++基础(3.内和对象)

目录 赋值运算符重载: const限制权限: 隐式类型转换: 再探构造函数: static成员: 有元: 内部类: 赋值运算符重载: 赋值运算符重载是一个默认成员函数,用于完成两个已经存在的对象直接的拷贝赋值.要注…

【STM32 HAL库】全双工I2S+双缓冲DMA的使用

1、配置I2S 我们的有效数据是32位的,使用飞利浦格式。 2、配置DMA **这里需要注意:**i2s的DR寄存器是16位的,如果需要发送32位的数据,是需要写两次DR寄存器的,所以DMA的外设数据宽度设置16位,而不是32位。…

pgsql的update语句在set里进行字段的运算 SET sort = sort +1

一、场景 需求:version 版本字段是记录数据更新的次数,新增时自动填充 version1 ,每更新一次数据 version就自增1。项目里单表插入和更新要手写update语句进行插入和更新。 –表中int4类型的字段 version 是1时,由1变成2 – version 是null…

嵌入式人工智能(10-基于树莓派4B的DS1302实时时钟RTC)

1、实时时钟(Real Time Clock) RTC,全称为实时时钟(Real Time Clock),是一种能够提供实时时间信息的电子设备。RTC通常包括一个计时器和一个能够记录日期和时间的电池。它可以独立于主控芯片工作&#xff…

5.过滤器Filter(doFilter()+chain.doFilter())

过滤器Filter 文章目录 过滤器Filter一、过滤器简介1.定义2.作用3.拦截原理4.常用方法:5.Filter的生命周期4.web.xml中配置5.WebFilter 一、过滤器简介 1.定义 过滤器是对Web应用程序的请求和响应添加功能的Web服务组件(实现 javax.servlet.Filter 接口的 Java 类。) 调用web…

Neuralink首款产品Telepathy:意念控制设备的革新与挑战

近年来,科技领域不断涌现出令人惊叹的突破,其中尤以脑机接口(BCI)技术为代表。近日,Elon Musk的Neuralink公司发布了其首款脑机接口产品Telepathy,引发了广泛关注。本文将详细探讨Telepathy的功能、技术原理…

Java语言程序设计基础篇_编程练习题**15.6(两个消息交替出现)

**15.6(两个消息交替出现) 编写一个程序,当单击鼠标时面板上交替显示两个文本"Java is fun"和"Java is powerful" 代码展示:编程练习题15_6TwoInfo.java package chapter_15;import javafx.application.Application; import javafx…

JavaScript之Web APIs-DOM

目录 DOM获取元素一、Web API 基本认知1.1 变量声明1.2 作用和分类1.3 DOM树1.4 DOM对象 二、获取DOM对象2.1 通过CSS选择器来获取DOM元素2.2 通过其他方式来获取DOM元素 三、操作元素内容3.1 元素.innerTest属性3.2 元素.innerHTML属性 四、操作元素属性4.1 操作元素常用属性4…

mysql无法启动

总是报错: 1、Job for mysql.service failed because the control process exited with error code. See "systemctl status mysql.service" and "journalctl -xeu mysql.service" for details. 2、ERROR 2002 (HY000): Cant connect to local …

Linux可视化工具-netdata之docker安装

版本要求 docker cli安装 docker pull netdata/netdata docker run -d --namenetdata \ --pidhost \ --networkhost \ -v netdataconfig:/etc/netdata \ -v netdatalib:/var/lib/netdata \ -v netdatacache:/var/cache/netdata \ -v /:/host/root:ro,rslave \ -v /etc/passwd…

常用注意力机制 SENet CBAM ECA

在处理脑电信号时通常会用到一些注意力机制,来给不同的脑电通道不同的权重,进而体现出不同脑电通道在分类中的重要性。下面整理几种常见的通道注意力机制,方便以后查阅。 常用注意力机制 SENet CBAM ECA 注意力机制SENet(Squeeze-and-Excitation Network)SENet原理SENet P…

五. TensorRT API的基本使用-load-model

目录 前言0. 简述1. 案例运行2. 代码分析2.1 main.cpp2.2 model.hpp2.3 model.cpp2.4 其它 总结下载链接参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》,链接。记录下个人学习笔记,仅供自己参考 本次课程我们来学习课程第五章—TensorRT …

达梦数据库审计日志采集

目录 1. 审计功能简介2. dm8官方技术参考文档3. dm8审计功能配置3.1 登录审计用户3.2 开启审计开关3.3 查询审计日志3.4 审计设置3.4.1 配置语句级审计3.4.2 取消语句级审计3.5 审计日志查阅4. python获取dm8审计日志1. 审计功能简介 审计机制是 DM 数据库管理系统安全管理的重…

第十一课:综合项目实践

下面是我们搭建的一个综合实践的拓扑图: 我们要完成以下目标: 网络中有3个不同部门,均可自动获取地址各部门可相互访问,也可访问内部服务网172.16.100.1,PC1不允许访问互联网,PC1和PC3可以访问互联网内网服…

nginx配置文件说明

Nginx的配置文件说明 Nginx配置文件的主要配置块可以分为三个部分:全局配置块(events和http块),events块和http块。这三个部分共同定义了Nginx服务器的整体行为和处理HTTP请求的方式。 全局配置块: 包含了影响Nginx服…