JavaScript系列——原型、原型链、继承

news2024/11/26 9:39:08

文章目录

    • 前置话题
    • 原型
      • 定义
      • 作用
      • 例子说明
      • 获取对象原型
    • 原型链
      • 定义
      • 例子说明
      • 原型链演示图
    • JavaScript 继承
      • 通过构造函数继承
        • 代码示例
    • 自有属性
    • 小结
    • 更多内容

前置话题

JavaScript 是一门面向对象的编程语言,其中有一个特征就是可继承性,和java编程语言不同,JavaScript拥有自己独特的方式,其继承可以通过原型、原型链机制来完成,下面对两个概念和工作原理进行说明。

原型

定义

原型是JavaScript 对象的一个内置属性,我们称为prototype,它本身就是一个对象。一般地,这个原型对象值指向 其构造函数的prototype

实际上prototype名称不是标准的,所有浏览器都是用 __proto__ 来表示对象原型的名称(普通对象和函数都有),但prototype 属性是构造函数专有的,如Date.prototype。

作用

在编程时候,我们可以把一些属性和方法,绑定到对象的原型对象上,通过这个对象构造出来的实例,就具备访问这些属性和方法的权限和能力

例子说明

下面代码我们定义一个myObject 对象,给他定义一个city 属性和greet 方法

const myObject = {
  city: "Madrid",
  greet() {
    console.log(`来自 ${this.city} 的问候`);
  },
};
myObject.greet(); // 来自 Madrid 的问候

如果你在控制台中输入对象的名称,然后跟随一个小数点(如同 myObject.),控制台会列出该对象可用的一系列属性。你会看到,除了 city 和 greet 外,还有很多其他属性!

__defineGetter__
__defineSetter__
__lookupGetter__
__lookupSetter__
__proto__
city
constructor
greet
hasOwnProperty
isPrototypeOf
propertyIsEnumerable
toLocaleString
toString
valueOf

虽然我们只是定义了 city 和 greet ,但myObject 是一个对象,他有原型,这些额外的属性就是通过原型链查找得到。基本所有对象的顶级原型都是指向Object.prototype,这些额外方法和属性,来自Object.prototype

因为原型本身就是一个对象,因此他也有自己的原型,这样一层层嵌套,就成了链,也就是原型链形成的原因。

获取对象原型

 Object.getPrototypeOf(object)//我们可以通过这个方式获取对象的原型

原型链

定义

JavaScript只有一种结构:对象,每个对象(object)都有自己的私有属性指向原型对象,而原型也是对象,它也有自己的原型,层层向上直到一个对象的原型为null。这些的方式就串成一个链,我们称之为原型链。

例子说明

我们通过Date 构造函数,创建一个 date实例,指向object 变量,然后通过 Object.getPrototypeOf 方法通过原型链,寻找各个节点原型对象。

const myDate = new Date();
let object = myDate;

do {
  object = Object.getPrototypeOf(object);
  console.log(object);
} while (object);

// Date.prototype
// Object { }
// null

原型链演示图

基于以上代码得到原型链图例如下:

  1. myDate 的原型指向 Date.prototype ,
  2. Date.prototype 原型指向 Object.prototype,
  3. Object.prototype 原型指向null

在这里插入图片描述

JavaScript 继承

通过构造函数继承

在 JavaScript 中,所有的函数都有一个名为 prototype 的属性。当你调用一个函数作为构造函数时,这个属性被设置为新构造对象的原型(按照惯例,在名为 proto 的属性中)。

因此,我们可以定义一个函数,通过重新指向函数的prototype的对象,在这个对象定义我们需要继承属性和方法,通过这个函数创建出来的所有实例,都可以继承这些方法和属性。

代码示例
const personPrototype = {
  greet() {
    console.log(`你好,我的名字是 ${this.name}`);
  },
};

function Person(name) {
  this.name = name;
}
Person.prototype.greet = personPrototype.greet;
// 或
// Object.assign(Person.prototype, personPrototype);

这里我们:

  1. 创建了一个 personPrototype 对象,它具有 greet() 方法
  2. 创建了一个 Person() 构造函数,它初始化了要创建人物对象的名字

然后我们 将 personPrototype 中定义的方法绑定到 Person 函数的 prototype 属性上。

在这段代码之后,使用 Person() 创建的对象将获得 Person.prototype 作为其原型,其中自动包含 greet 方法。

const reuben = new Person("Reuben");
reuben.greet(); // 你好,我的名字是 Reuben!

自有属性

我们使用上面的 Person 构造函数创建的对象有两个属性:

  1. name 属性,在构造函数中设置,在 Person 对象中可以直接看到
  2. greet() 方法,在原型中设置

直接在对象中定义的属性,如这里的name,被称为自有属性,你可以使用静态方法 Object.hasOwn() 检查一个属性是否是自有属性:

除此之外:
你也可以在这里使用非静态方法 Object.hasOwnProperty(),但我们推荐尽可能使用 Object.hasOwn() 方法。

const irma = new Person("Irma");

console.log(Object.hasOwn(irma, "name")); // true
console.log(Object.hasOwn(irma, "greet")); // false

如果改变name的值,比如 irma.name = “jack”, 此方式不会通过原型链访问,而是直接通过将值绑定到irma 对象上,通过以下代码演示:

const personPrototype = {
  greet() {
    console.log(`你好,我的名字是 ${this.name}`);
  },
 age:18,
};

function Person(name) {
  this.name = name;
}
Person.prototype = personPrototype;
const reuben = new Person("Reuben");
renben.age //18
renben.age = 20 
renben.age //20 
const __proto__ = Object.hasOwnProperty(renben) //personPrototype 
__proto__.age //18 ,age 没有改变

在 personPrototype 中,添加一个age 属性,值为18,通过原型绑定到Person 构造函数中
执行renben.age = 20 ,并没有改变 Person.prototype 的对象age 值

小结

  1. 基本所有对象都具有私有属性__proto__(除了null),原型对象就存储在这个对象上,我们可以通过Object.getPrototypeOf获取;

  2. prototype 是函数对象独有的,我们可以将需要继承的方法和属性绑定在函数的prototype对象上,通过这个函数构造出来的实例,都可以访问这些属性和方法。

  3. 当访问一个对象本身自己没有的属性或者方法时,JavaScript会通过原型链的查找机制,逐层向上查找其构造函数.prototype 有没有这个属性和方法,直到末端为止。

更多内容

更多内容请关注下方微信二维码
在这里插入图片描述

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

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

相关文章

史上最全,资深测试老鸟-接口测试总结,看这篇就足够了...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、什么是接口 接…

R语言基础 | 安徽某高校《统计建模与R软件》期末复习

第一节 数字、字符与向量 1.1 向量的赋值 c<-(1,2,3,4,5) 1.2 向量的运算 对于向量&#xff0c;我们可以直接对其作加&#xff08;&#xff09;&#xff0c;减&#xff08;-&#xff09;&#xff0c;乘&#xff08;*&#xff09;&#xff0c;除&#xff08;/&#xff09…

Python数据科学视频讲解:特征决策树分箱

5.3 特征决策树分箱 视频为《Python数据科学应用从入门到精通》张甜 杨维忠 清华大学出版社一书的随书赠送视频讲解5.3节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。内容涵盖数据科学应用的全流程&#xff0c;包括数据科学应…

网络安全行业证书【含金量排名】

文章目录 一、前言二、CISP三、CISAW四、NISP五、为什么很多人考不下来 一、前言 现在想找网络安全之类的工作&#xff0c;光有技术是不够的&#xff0c;还得有东西证明自己&#xff0c;网安三大敲门砖&#xff1a;CTF、漏洞证明和专业证书。 对于CTF的话只是少数人能参加的…

Lambda表达式超详解

目录 背景 Lambda表达式的用法 函数式接口 Lambda表达式的基本使用 语法精简 变量捕获 匿名内部类 匿名内部类中的变量捕获 Lambda的变量捕获 Lambda表达式在类集中的使用 Collection接口 List接口 Map接口 总结 背景 Lambda表达式是Java SE 8中的一个重要的新特性.…

swing快速入门(二十七)

注释很详细&#xff0c;直接上代码 上一篇 新增内容 1.为按钮指定图标 2. 列表框的并列 3.菜单项绑定快捷键 4.控件悬浮提示信息 5.菜单项设置小图标 6.五种布局风格右键选择切换 package swing21_30;import javax.swing.*; import java.awt.*; import java.awt.event.…

JBoss 5.x/6.x 反序列化 CVE-2017-12149 已亲自复现

JBoss 5.x/6.x 反序列化 CVE-2017-12149 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 漏洞名称 漏洞描述 2017年8月30日&#xff0c;厂商Redhat发布了一个JBOSSAS 5.x 的反序列化远程代码执行漏洞通告。该漏洞位于JBoss的HttpInvoker组件中的…

HALCONVS .net混合编程案例【02】:检测芯片的管脚间距

前言&#xff1a; 本章给出的HALCON和Visual Studio的WPF项目中联合编程的案例。 VS中WPF的编程&#xff0c;UI的设计非常方便&#xff0c;如果结合HALCON的算法&#xff0c;可以很快实施机器视觉相关的应用。本例的应用&#xff0c;实现了自动检测的一个三洋的芯片的管脚的间…

实验五 用户进程管理-实验部分

目录 一、知识点 1.Unix进程创建API 1.1.创建新进程API 1.2.fork()地址空间的复制 1.4.shell中调用fork()图示 1.5.fork()创建进程个数示例 1.6.fork()与exec()的比较 2.实验执行流程概述 3.创建用户进程 3.1.应用程序的组成和编译 3.2.用户进程的虚拟地址空间 3.3…

初识QT(上篇):What Qt

初识QT&#xff08;上篇&#xff09;&#xff1a;What Qt 前言 & 说明前言说明 初识QT1.1 QT的what1. 介绍2. 发展历程3. QT架构的主要内容4.QT的常用模块 1.2 QT的 why1. QT的核心机制 下篇笔记链接 前言 & 说明 前言 前言&#xff1a; 之前说要share的qt相关知识&am…

Hadoop入门学习笔记——五、在虚拟机中部署Hive

视频课程地址&#xff1a;https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接&#xff1a;https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 Hadoop入门学习笔记&#xff08;汇总&#xff09; 目录 五、在虚拟机中部署Hive5.1. 在node1虚拟机安装MySQL5.2.…

正餐---二叉树的OJ题

目录​​​​​​​ 前言&#x1f36f; 1. 检查两颗树是否相同&#x1f947; 1.1 思路分析&#x1fa99; 1.2 代码实现&#x1f9f0; 2. 单值二叉树&#x1f332; 2.1 思路分析&#x1f52e; 2.2 代码实现&#x1f488; 3. 二叉树的前序遍历&#x1f39f;️ 3.1 思路分…

鲜花植物企业网站建设的效果如何

从整体来看&#xff0c;似乎鲜花植物只会在线下花市或花店里购买或见到&#xff0c;但其实对鲜花植物批发商或品牌商来说&#xff0c;线上渠道同样重要&#xff0c;从本地来说&#xff0c;流量少且获取难&#xff0c;各家品牌/门店竞争激烈&#xff0c;并且无法全面展示自己的品…

基于模型驱动的可解释性全色、多光谱、高光谱融合网络

摘要 摘要:同时融合高光谱(HS)、多光谱(MS)和全色(PAN)图像为生成高分辨率HS (HRHS)图像提供了一种新的范式。在这项研究中&#xff0c;我们提出了一个可解释的模型驱动的深度网络&#xff0c;用于HS, MS和PAN图像融合&#xff0c;称为HMPNet。我们首先提出了一种新的融合模型…

计算机组成原理第6章-(计算机的运算方法)【上】

机器数与真值 把符号“数字化”的数称为机器数,而把带“+”、“-”符号的数称为真值。 原码表示法 原码是机器数中最简单的一种表示形式,0表示整数,1表示负数。 约定整数的符号位和数值位之间用“逗号”隔开。 在原码中,0有两种表示形式:“+0”和“-0”是不一样的。 反…

毅速:3D打印随形水路已经逐步向压铸模具普及

随着科技的不断发展&#xff0c;3D打印技术已经逐渐渗透到各个领域。其中&#xff0c;3D打印随形水路在注塑模具中已经广泛应用&#xff0c;目前正逐渐向压铸模具普及。 传统CNC等减材工艺的水路制造&#xff0c;可以在模具中生产出平直的冷却水路&#xff0c;但这种工艺难以加…

Qt/C++视频监控Onvif工具/组播搜索/显示监控画面/图片参数调节/OSD管理/祖传原创

一、前言 能够写出简单易用而又不失功能强大的组件&#xff0c;一直是我的追求&#xff0c;简单主要体现在易用性&#xff0c;不能搞一些繁琐的流程和一些极难使用的API接口&#xff0c;或者一些看不懂的很难以理解的函数名称&#xff0c;一定是要越简单越好。功能强大主要体现…

百度网盘win11端扫一扫登录二维码无法显示问题的解决方法

百度网盘win11端扫一扫登录二维码无法显示问题的解决方法 文章目录 问题描述解决方法1、打开Edge 设置2、进入Reset settings页面3、单击重置按钮&#xff1a;4、重新打开百度网盘APP 问题描述 今天在win11端扫描登录百度云网盘时&#xff0c;二维码无法加载出来&#xff0c;具…

PCIe surprise down异常与DPC功能分析-part2

DPC是PCIe协议中的一项功能&#xff0c;旨在防止由于一个设备的错误而影响到整个系统。当一个PCIe设备检测到严重的、不可恢复的错误时&#xff0c;它可能会触发DPC过程。在这个过程中&#xff0c;PCIe开关会隔离受影响的下游端口&#xff0c;阻止任何进一步的数据传输和请求通…

中北大学 软件构造 U+及上课代码详解

作业1 1.数据类型可分为两类:(原子类型) 、结构类型。 2.(数据结构)是计算机存储、组织数据的方式&#xff0c;是指相互之间存在一种或多种特定关系的数据元素的集合 3.代码重构指的是改变程序的(结构)而不改变其行为&#xff0c;以便提高代码的可读性、易修改性等。 4.软件实…