js中原型和原型链的理解(透彻)

news2024/11/18 10:14:03

js中原型、原型链、继承的理解(透彻)

  • 1、前言
    • 1.1 什么是函数对象
    • 1.2 什么是实例对象
    • 1.3 什么是原型对象
    • 1.4 构造函数、原型对象、实例对象的关系
  • 2、原型
  • 3、原型链
  • 4、原型的相关属性及方法
  • 5、总结

1、前言

1.1 什么是函数对象

函数对象就是我们平时称呼的函数,构造函数也包含其中,在这里我们说一说构造函数与普通函数的区别。

构造函数也是一个普通函数,和普通函数的主要区别在于调用方式不一样,作用也不一样(构造函数用来构建实例对象)。

普通函数:

function person(){
  console.log(this);  // Window
}
person()

构造函数:

function Person() {
  console.log(this);  // Person{}
}
let p = new Person();

1.2 什么是实例对象

ES5:

// ES5:生成实例对象的传统方法是通过构造函数
function Person(name, age) {
    this.name = name;
    this.age = age;
}
 
Person.prototype.sayName = function () {
    alert(this.name);
};
 
var person1 = new Person("张三", 29);
var person2 = new Person("李四", 27);

ES6:

// ES6可通过class关键字定义类
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    sayName() {
        alert(this.name);
    }
}
 
// ES6使用类时也是直接对类使用new命令
var person1 = new Person("Nicholas", 29);
var person2 = new Person("Greg", 27);

person1和person2都是Person类的实例对象(实例都是对象)

1.3 什么是原型对象

我们在创建函数的同时,浏览器会在内存中创建一个对象。这个函数中默认有一个prototype属性,指向了该对象。这个对象就是函数的原型对象,简称函数的原型。

每个构造函数都有一个原型对象存在,这个原型对象通过构造函数的prototype属性来访问。原型对象默认会有一个constructor属性指向构造函数。

1.4 构造函数、原型对象、实例对象的关系

构造函数、原型对象、实例对象的关系:

①每个构造函数都有一个prototype属性,这个属性指向了原型对象。

②每个实例对象都有一个__proto__属性,这个属性指向了对象的原型对象。

③在原型对象里有一个constructor属性,该属性指向了构造函数。

在这里插入图片描述

2、原型

在 JavaScript中,每当定义一个对象(函数也是对象)时候,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype属性,这个属性指向函数的原型对象,使用原型对象的好处是所有对象实例共享它所包含的属性和方法。

3、原型链

每个对象拥有一个原型对象,通过 proto 指针指向其原型对象,并从中继承方法和属性,同时原型对象也可能拥有原型,这样一层一层,最终指向
null(Object.proptotype.__proto__指向的是null)。这种关系被称为原型链(prototype chain),通过原型链一个对象可以拥有定义在其他对象中的属性和方法。

4、原型的相关属性及方法

三个属性:prototype、proto、constructor;
一个方法:hasOwnProperty()

★ prototype:每个函数都有一个prototype属性,这个属性指向函数的原型对象。
★ proto:每个对象(除null外)都会有的属性,叫做__proto__,这个属性会指向该对象的原型。
★ constructor:每一个原型都有一个constructor属性,指向该关联的构造函数。
prototype 和 proto 区别是什么?
● prototype是构造函数的属性
● __proto__是每个实例都有的属性,可以访问 [[prototype]] 属性
● 实例对象的__proto__与其构造函数的prototype指向的是同一个对象
★ hasOwnProperty() 方法
它的作用是判断函数的原型所在位置。一个对象本身添加的属性返回true,在原型中的属性和不存在的属性都会返回false。

//创建构造函数
function Person(){

}
//使用Person.prototype直接访问到原型对象
// 给Person函数的原型对象中添加一个属性name,值是"小明"
// Person.prototype.name = "小明";
Person.prototype = {
    constructor:Person,   //让constructor重新指向Person函数
    /*如果直接给Person的原型指定对象字面量(没有上面这一行),
      这个对象的constructor属性不再指向Person函数*/
    name: "小明"
};
 
//创建一个实例对象p1
var p1 = new Person();
 
//访问p1对象的属性name
p1.age = 18;
 
console.log(Person.prototype.constructor === Person);  // true
 
//如果在Person.prototype中没有constructor:Person这一行代码则输出flase
//Person.prototype.name = "小明";这种写法输出也是true
 
console.log(p1.__proto__ === Person.prototype);  // true
 
//如果在Person.prototype中没有constructor:Person这一行代码则输出flase
//Person.prototype.name = "小明";这种写法输出也是true
 
console.log(p1.name);  // 小明  
 
/*虽然在p1对象中没有明确的添加属性name,但是仍然可以成功打印的原因是:
  p1的__proto__属性指向的原型中有name属性,所以可以访问到属性name值。*/
 
console.log(p1.hasOwnProperty("age"));  // true
//因为age属性是直接在p1属性中添加的

console.log(p1.hasOwnProperty("name"));  // false 
//因为name属性是在原型中添加的

console.log(p1.hasOwnProperty("sex"));  // false 
//因为sex属性不存在

5、总结

  • JavaScript中的对象,都有一个内置属性[Prototype],指向这个对象的原型对象。当查找一个属性或方法时,如果在当前对象中找不到,会继续在当前对象的原型对象中查找;如果原型对象中依然没有找到,会继续在原型对象的原型中查找(原型也是对象,也有它自己的原型);直到找到为止,或者查找到最顶层的原型对象中也没有找到,就结束查找,返回undefined。这个查找过程是一个链式的查找,每个对象都有一个到它自身原型对象的链接,这些链接组建的整个链条就是原型链。拥有相同原型的多个对象,他们的共同特征正是通过这种查找模式体现出来的。
  • 在上面的查找过程,我们提到了最顶层的原型对象,这个对象就是Object.prototype,这个对象中保存了最常用的方法,如toString、valueOf、hasOwnProperty等,因此我们才能在任何对象中使用这些方法。

在这里插入图片描述

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

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

相关文章

centos连接XShell

先设置网络自动连接,为Xshell 连接centos做准备 选择应用程序->系统工具->设置 选择网络,如果有线没有打开,选择打开,在点击设置 记住ipv4地址,选择自动连接,然后应用 最后鼠标右键点击桌面&#xf…

RabbitMQ入门案例之Topic模式

前言: 本文章将介绍RabbitMQ中的Topic(主题)模式,其中还会涉及 ‘#’ 和 ‘*’ 两个通配符在RabbitMQ中的区别。 官网文档地址:https://rabbitmq.com/getstarted.html 什么是Topic模式 RabbitMQ的Topic模式是一种基于…

SpringBoot 如何使用 Spring Integration 处理事件

SpringBoot 如何使用 Spring Integration 处理事件 Spring Integration 是 Spring Framework 的一个扩展,它提供了一种基于消息传递的集成模式。使用 Spring Integration,我们可以将不同的应用程序、系统和服务连接起来,从而实现数据的传递、…

VMware中Linux虚拟机配置静态ip

一、输入ip addr查看ip地址 二、输入cd /etc/sysconfig/network-scripts进入centos网络配置文件夹 三、接着输入ls查看目录 四、 输入vi ifcfg-ens33进入网卡配置 五、 进入以后是这个界面,红色方框里的内容是需要手动修改的,下面图片里已经修改过了。 …

【C】分支和循环语句的简单介绍

语句 分支语句if语句语法结构代码演示 switch语句语法结构代码演示 循环语句while循环语法结构代码分析 for循环语法结构代码演示 do...while循环语法结构代码分析 什么是语句呢? 在C语言中由分号(;)隔开的就是一条语句。 分支语句 if语句 …

【算法设计与分析】期末考试知识总结(知识超浓缩版)

目录 简要介绍 复杂度 迭代 插入排序 二分查找 快排划分 选择排序 计数排序 基数排序 桶排序 递归 递归式的计算-四种方法 欧几里得算法 汉诺塔问题 快速排序 归并排序 堆排序 分治 二维极大点问题 一维最邻近点对 二维最邻近点对 逆序对的数目 凸包 最大字段…

RecyclerView 低耦合单选、多选模块实现

作者:丨小夕 前言 需求很简单也很常见,比如有一个数据列表RecyclerView,需要用户去点击选择一个或多个数据。 实现单选的时候往往简单下标记录了事,实现多选的时候就稍微复杂去处理集合和选中。随着项目选中需求增多&#xff0c…

k8s的部署

二进制搭建 Kubernetes v1.20 k8s集群master01:192.168.92.30 kube-apiserver kube-controller-manager kube-scheduler etcd k8s集群master02:192.168.92.21 k8s集群node01:192.168.92.40 kubelet kube-proxy docker k8s集群node02…

阿里云热修复打补丁包注意事件

1、每次发布app到应用市场前,注意保存没有加固前的apk文件和mapping.txt 2、修复好bug,打包app前,要做的事情 (1)先把有问题的apk的mapping.txt文件复制到/app路径下 (2)修改混淆配置:将-printmapping mapping.txt使…

Android蓝牙协议知识汇总

蓝牙协议下载 蓝牙技术联盟网址:https://www.bluetooth.com/ 在这个网址搜索,比如: 在搜索结果中找到蓝牙协议规范: 点击上面网址: 蓝牙手册里包含了部分核心协议,比如L2CAP、SDP、ATT、GATT&#x…

Python 100%解析svg-captcha验证码

前言 前段时间接到一个需求,登陆某一个网站,然后录入数据;本来以为是一个很简单的需求,结果遇到几个难点: 登陆的时候需要有验证码验证码是一个请求路径,每请求一次验证码都不一样 本来一开始以为是常用的…

探究 CoreData 使用索引(Index)机制加速查表究竟如何实现?

问题现象 在  App 的开发中,CoreData 到底能不能用索引机制(Index)来加速查表?如果可以,又该如何创建和使用索引呢? 这是一个连  官方文档都模棱两可,Stackoverflow 里诸多大神都闪烁其词的话题。 在本篇博文中,您将学到如下内容: 什么是 CoreData 索引(Index…

SpringBoot + Ant Design Vue实现数据导出功能

SpringBoot Ant Design Vue实现数据导出功能 一、需求二、前端代码实现2.1 显示实现2.2 代码逻辑 三、后端代码实现3.1 实体类3.2 接收参数和打印模板3.3 正式的逻辑3.4 Contorller 一、需求 以xlsx格式导出所选表格中的内容要求进行分级设置表头颜色。 二、前端代码实现 2…

20230524 taro+vue3+webpack5+pdfjs时打包pdfjs进不来的问题

关闭taro的terser就可以了 terser:{enable:false }

UE中创建异步任务编辑器工具(Editor Utility Tasks)

在UE中我们往往需要执行一些编辑器下的异步任务,例如批量生成AO贴图、批量合并静态模型等,又不想阻碍主线程,因此可以使用Editor Utility Tasks直接创建UE编辑器下的异步任务。 如果你不太了解UE编辑器工具,可以参考这篇文章&…

Spring Boot 中自定义数据校验注解

Spring Boot 中自定义数据校验注解 在 Spring Boot 中,我们可以使用 JSR-303 数据校验规范来校验表单数据的合法性。JSR-303 提供了一些常用的数据校验注解,例如 NotNull、NotBlank、Size 等。但是,在实际开发中,我们可能需要自定…

2023年6月24日(星期六):骑行明郎

2023年6月24日(星期六):骑行明郎,早8:30到9:00, 大观公园门囗集合,9:30点准时出发 【因迟到者,骑行速度快者,可自行追赶偶遇。】 偶遇地点: 大观公园门囗集合,家住南,东&#xff0c…

(二叉树) 100. 相同的树 ——【Leetcode每日一题】

❓100. 相同的树 难度:简单 给你两棵二叉树的根节点 p 和 q,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 示例 1: 输入:p [1,2,3], q …

使用代理ip做网页抓取需要注意什么

现在,很多公司为达成目标,都需要抓取大量数据。企业需要根据数据来作出重大决定,因此掌握准确信息至关重要。互联网上有许多宝贵的公共数据。问题是如何轻松采集这些数据,而无需让团队整天手动复制粘贴所需信息?网页抓取的定义越…

Qt学习11:Dialog对话框操作总结

文章目录 QDialogQDialogButtonBoxQMessageBoxQFileDialogQFontDialogQColorDialogQInputDialogQProgressDialog 文章首发于我的个人博客:欢迎大佬们来逛逛 QDialog Qt中使用QDialog来实现对话框,QDialog继承自QWidget,对话框分为**三种**&…