前端JavaScript篇之对原型、原型链的理解、原型修改、重写、原型链指向

目录

  • 对原型、原型链的理解
  • 原型修改、重写
    • 修改原型
    • 重写原型
    • 修改和重写原型的影响
    • 案例代码
  • 原型链指向


对原型、原型链的理解

原型(Prototype)是JavaScript中每个对象都具有的属性,它包含对象的共享属性和方法。当我们创建一个新对象时,这个对象会从原型继承属性和方法。原型链(Prototype Chain)是由对象组成的链式结构,它用于查找对象的属性和方法。当我们访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript引擎会沿着原型链向上查找,直到找到匹配的属性或方法。

在JavaScript中,使用构造函数来新建一个对象,每个构造函数都有一个内部的prototype属性,它的属性值是一个对象,包含了可以由该构造函数的所有实例共享的属性和方法。当使用构造函数新建一个对象后,对象内部将会包含一个指向构造函数的prototype属性对应的值的指针,这个指针被称为对象的原型。通过原型链,对象可以从原型继承属性和方法。

在访问一个对象的属性时,如果对象内部不存在这个属性,就会去它的原型对象中查找这个属性,并继续通过原型链向上查找,直到找到匹配的属性。原型链的尽头一般是Object.prototype。

通过原型和原型链的机制,可以实现对象的继承和共享属性和方法。原型和原型链是JavaScript中非常重要的概念,对于理解对象的继承和属性查找机制至关重要。

原型修改、重写

在JavaScript中,可以修改或重写对象的原型。当修改原型时,所有与该原型相关的对象都会继承这一改变。下面是对修改和重写原型的详细描述:

修改原型

修改原型是指向现有原型添加新的属性或方法。我们可以通过给原型对象添加新的属性或方法来实现这一点。

在下面的代码中,我们向Person构造函数的原型添加了一个新的getName方法:

function Person(name) {this.name = name
}
// 修改原型
Person.prototype.getName = function() {}

在这个例子中,我们给Person构造函数的原型添加了一个新的getName方法。现在,所有Person对象的实例都可以使用这个方法。

重写原型

重写原型是指用一个新的对象来替换现有原型。我们可以通过直接赋值一个新的对象给原型来实现这一点。

在下面的代码中,我们用一个新的对象来替换Person构造函数的原型:

Person.prototype = {getName: function() {}
}

在这个例子中,我们用一个新的对象来替换Person构造函数的原型。现在,所有Person对象的实例都会继承这个新的原型对象。

修改和重写原型的影响

修改和重写原型都会对与原型相关的对象产生影响。当我们修改原型时,所有与该原型相关的对象都会继承这一改变。当我们重写原型时,与原型相关的对象将不再继承原型中的属性和方法,而是继承新的原型对象中的属性和方法。

案例代码

在下面的代码中,我们先修改了Person构造函数的原型,然后创建了一个Person对象的实例p。我们使用__proto__属性和constructor属性来检查p对象的原型和构造函数。

function Person(name) {this.name = name
}
// 修改原型
Person.prototype.getName = function() {}
var p = new Person('hello')
console.log(p.__proto__ === Person.prototype) // true
console.log(p.__proto__ === p.constructor.prototype) // true

接下来,我们重写了Person构造函数的原型,然后再次创建了一个Person对象的实例p。我们再次使用__proto__属性和constructor属性来检查p对象的原型和构造函数。

// 重写原型
Person.prototype = {getName: function() {}
}
var p = new Person('hello')
console.log(p.__proto__ === Person.prototype)        // true
console.log(p.__proto__ === p.constructor.prototype) // false

我们可以看到,当我们重写原型时,p对象的构造函数不再指向Person构造函数,而是指向根构造函数Object。因此,此时p.constructor === Object,而不是p.constructor === Person。为了让p.constructor === Person,我们需要将它手动指回来,如下所示:

Person.prototype = {getName: function() {}
}
var p = new Person('hello')
p.constructor = Person
console.log(p.__proto__ === Person.prototype)        // true
console.log(p.__proto__ === p.constructor.prototype) // true
  • 修改原型是指向现有原型添加新的属性或方法。
  • 重写原型是指用一个新的对象来替换现有原型。
  • 修改和重写原型都会对与原型相关的对象产生影响。
  • 当我们重写原型时,相关对象的构造函数可能会指向根构造函数Object,需要手动将其指回来。

原型链指向

在 JavaScript 中,每个对象都有一个原型(prototype)。原型是一个对象,它包含对象的共享属性和方法。当我们创建一个新对象时,这个对象会从原型继承属性和方法。

在 JavaScript 中,对象之间的原型关系构成了原型链。原型链是由对象组成的链式结构,用于查找对象的属性和方法。当我们访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript 引擎会沿着原型链向上查找,直到找到匹配的属性或方法。

对于一个对象p,我们可以通过p.__proto__来访问它的原型对象。例如,对于一个Person对象的实例pp.__proto__指向Person.prototype

对于一个原型对象,我们可以通过prototype.__proto__来访问它的原型对象。例如,对于Person.prototypePerson.prototype.__proto__指向Object.prototype

对于一个对象p,我们可以通过p.__proto__.__proto__来访问它的原型对象的原型对象。例如,对于一个Person对象的实例pp.__proto__.__proto__指向Object.prototype

对于一个对象p,我们还可以通过p.__proto__.constructor.prototype.__proto__来访问它的构造函数的原型对象的原型对象。例如,对于一个Person对象的实例pp.__proto__.constructor.prototype.__proto__也指向Object.prototype

对于一个原型对象,我们可以通过prototype.constructor来访问它的构造函数。例如,对于Person.prototypePerson.prototype.constructor指向Person构造函数。

对于一个对象p,我们可以通过p.__proto__.constructor来访问它的构造函数。例如,对于一个Person对象的实例pp.__proto__.constructor指向Person构造函数。

function Person(name) {this.name = name
}var p = new Person('John')
var p1 = new Person('Mike')console.log(p.__proto__) // Person.prototype
console.log(Person.prototype.__proto__) // Object.prototype
console.log(p.__proto__.__proto__) // Object.prototype
console.log(p.__proto__.constructor.prototype.__proto__) // Object.prototype
console.log(Person.prototype.constructor.prototype.__proto__) // Object.prototype
console.log(p1.__proto__.constructor) // Person
console.log(Person.prototype.constructor) // Person

请添加图片描述

注意事项:

  1. 在 ES6 中,我们可以使用Object.getPrototypeOf()方法来获取一个对象的原型对象。例如,Object.getPrototypeOf(p)可以替代p.__proto__

  2. 在修改原型对象时,需要注意对原型链的影响。如果我们修改了一个原型对象的属性或方法,那么所有继承自该原型对象的对象都会受到影响。

  3. 在使用原型继承时,需要注意避免出现原型链中的循环引用,否则会导致程序出现死循环。

持续学习总结记录中,回顾一下上面的内容:
在JavaScript中,每个对象都有一个指向另一个对象的链接,这个对象就是我们所说的原型。原型是JavaScript实现继承的核心机制之一。
当我们创建一个对象时,这个对象会自动关联一个原型。如果我们访问一个对象的属性或方法,但是这个对象本身并没有这个属性或方法,JavaScript引擎会沿着原型链向上查找,直到找到匹配的属性或方法为止。
原型链是由对象的原型构成的链式结构,当我们访问一个对象的属性或方法时,JavaScript引擎会沿着这条链去查找对应的属性或方法。
通过修改原型,我们可以给已存在的对象类型添加新的方法或属性。这意味着所有基于这个对象类型创建的对象都可以访问到这些新的方法或属性。
重写原型是指改变一个对象的原型,这样新的原型就会被所有基于该对象类型创建的对象所共享。
原型链的指向是指对象的原型是谁,它决定了对象在查找属性或方法时的搜索路径。一个对象的原型是另一个对象,而这个对象的原型又是另一个对象,以此类推,就形成了原型链。
总的来说,原型和原型链是JavaScript中实现继承的基础,通过它们,我们可以实现对象之间的属性和方法的共享,实现代码的复用,同时也可以通过修改原型和重写原型来扩展和改变对象的行为。

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

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

相关文章

数码管扫描显示-单片机通用模板

数码管扫描显示-单片机通用模板 一、数码管扫描的原理二、display.c的实现1、void Display(void) 各模式界面定义数据2、void BackupRamToDisRam(void)从缓存区刷新显示映射Ram3、void FreshDisplay(void) 映射显示Ram到主控的IO口4、void LcdDisplay_8bit(void) 映射显示Ram到…

Red Panda Dev C++ Maker 使用说明

https://download.csdn.net/download/HappyStarLap/88804678https://download.csdn.net/download/HappyStarLap/88804678 下载https://download.csdn.net/download/HappyStarLap/88804678: ​ 这个,就是我们将运行的文件。 ​ 里面加了许多我…

【java苍穹外卖项目实战二】苍穹外卖环境搭建

文章目录 1、前端环境搭建2、后端环境搭建1、项目结构搭建2、Git版本控制3、数据库创建 开发环境搭建主要包含前端环境和后端环境两部分。 前端的页面我们只需要导入资料中的nginx, 前端页面的代码我们只需要能看懂即可。 1、前端环境搭建 前端运行环境的nginx&am…

Python数据分析 可视化数据Seaborn图表 这篇就够了

目录 1.Seaborn图表概述 2.安装Seaborn图表 3.Seaborn图表的基本设置 3.1设置图表的背景风格 3.2 设置图表的边框 4.常见图表的绘制 41 .柱形图的绘制 4.2 折线图的绘制 4.3 散点图的绘制 1.Seaborn图表概述 Seaborn是一个基于Matplotlib的Python数据可视化库&#xff…

探索未来:集成存储器计算(IMC)与深度神经网络(DNN)的机遇与挑战

开篇部分:人工智能、深度神经网络与内存计算的交汇 在当今数字化时代,人工智能(AI)已经成为科技领域的一股强大力量,而深度神经网络(DNN)则是AI的核心引擎之一。DNN是一种模仿人类神经系统运作…

C++ 动态规划 树形DP 没有上司的舞会

Ural 大学有 N 名职员,编号为 1∼N 。 他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。 每个职员有一个快乐指数,用整数 Hi 给出,其中 1≤i≤N 。 现在要召开一场周年庆宴会,不过,没有职…

奇瑞汽车,好好卖车,别趟个人是非的浑水

文 | AUTO芯球 作者 | 雷歌 这下,奇瑞法务部忙都忙不过来了。 一个字,就是,告!告!告! 刚投诉完这家,又去告那家。 可是骂奇瑞的实在太多了,告不完,根本告不完。 有骂…

[day0] 借着“ai春晚”开个场

1 文思ai笔记-新的开始 今天是2024年2月29日,也是传统农历的除夕夜。早起在ai圈看到一个比较新奇的消息,ai春晚今日举办,竟然有一点小小的激动。这些年确实好久没看过春晚了,自己对于春晚的映像还停留在“白云黑土”、“今天&…

扑克牌大小(模拟)

题目 import java.util.Scanner; public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);String s sc.nextLine();String[] ss s.split("-");StringBuffer s1 new StringBuffer();StringBuffer s2 new StringBuffer(…

自适应二次元404页面源码

自适应二次元404页面源码,HTMLCSSJS,喜欢二次元的朋友可以下载使用 蓝奏云:https://wfr.lanzout.com/iuPNQ1ns7dxg

32I2C通信协议

异步时序的:非常依赖硬件外设的支持,比如串口是很难用软件来模拟的;但节省了一根时钟线的资源 同步时序可以极大地降低单片机对硬件电路的依赖,时钟线停止了,发送方和接收方都会停止 一.I2C通信协议简介 二.硬件电路…

springboot172基于springboot的二手车交易系统的设计与实现

二手车交易系统的设计与实现 摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统二手车交易信息管理难度大&…

第59讲订单数据下拉实现

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;/*** 订单查询 type值 0 全部订单 1待付款 2 待收货 3 退款/退货* param type* return*/RequestMapping("/list")public R list(Integer type,Integer page,Integer pageSize){System.out.pri…

C#,十进制展开数(Decimal Expansion Number)的算法与源代码

1 十进制展开数 十进制展开数(Decimal Expansion Number)的计算公式: DEN n^3 - n - 1 The decimal expansion of a number is its representation in base -10 (i.e., in the decimal system). In this system, each "decimal place…

Vue2中v-for 与 v-if 的优先级

在Vue2中,v-for 和 v-if 是常用的指令,它们在前端开发中非常有用。但是,当我们在同一个元素上同时使用这两个指令时,就需要注意它们的优先级关系了。 首先,让我们了解一下v-for和v-if的基本用法。 v-for 是Vue的内置…

【STL】list模拟实现

vector模拟实现 一、接口大框架函数声明速览二、结点类的模拟实现1、构造函数 三、迭代器类的模拟实现1、迭代器类存在的意义2、迭代器类的模板参数说明3、构造函数4、运算符的重载(前置和后置)(1)前置(2)后…

堆的概念实现

前言 本文将详细讲解堆。堆是一种二叉树(一般是完全二叉树)使用顺序结构的数组来存储。 tip:这里我们需要注意区分堆在不同地方的含义,这里的堆是一个数据结构,操作系统虚拟进程地址空间的堆是操作系统中管理内存的一块…

公众号天气推送源码,附带教学,自动版本推送带各种模板

公众号天气推送系统介绍 主要功能特点: 实时天气查询:用户可以通过公众号随时查询当前位置的实时天气状况,包括温度、湿度、风速、天气状况等详细信息。定时推送服务:系统支持自定义时间段的天气推送,确保用户在出门…

【项目问题解决】java. net.SocketException: Connection reset

目录 【项目问题解决】java. net.SocketException: Connection reset 1.问题描述2.问题原因3.解决思路4.解决方案5.总结6.参考 文章所属专区 项目问题解决 1.问题描述 通过JMeter 压测接口,无并发,无间歇时间跑接口10000次报错,后续改成建个…

JavaScript指针事件

🧑‍🎓 个人主页:《爱蹦跶的大A阿》 🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 随着移动设备的普及,触屏交互正在快速增长。指针事件提供了支持触控和…