关于原型链

news2024/11/26 0:48:13

1-__proto__([[Prototype]])prototype

每个对象都有一个隐式原型,这个隐式原型可以通过

obj.__proto__
Object.getPrototypeOf(obj)

这两种方式获取;
我们都知道对象是通过构造函数构造的,new关键字构造的,
构造函数上有一个显式原型属性,对象的隐式原型就指向了它的构造函数的显式原型。

 let obj1 = new Object()
 console.log(obj1.__proto__ == Object.prototype)//true

而这个构造函数也是一个函数对象对不对?所以构造函数的隐式原型对象也是指向函数的显式原型对象的。

console.log(Object.__proto__ == Function.prototype)

例子:

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

  }
  //通过构造函数得到两个实例对象
  let p1 = new Person()
  let p2 = new Person()
  console.log(p1.__proto__ == Person.prototype)//true
  //Person也是一个函数对象,是new Function的语法糖
  console.log(Person.__proto__ == Function.prototype)//true

所以,对象上只有隐式原型对象__proto__,而它的构造函数上因为既是函数又是函数对象,所以既有显式原型又有隐式原型对象,一个对象的隐式原型指向它的构造函数的显式原型。

原型对象上的constructor属性

指向当前的构造函数

console.log(p1.__proto__.constructor)
console.log(Person.prototype.constructor)
console.log(Function.prototype.constructor)

在这里插入图片描述

原型链是什么?

每个对象有一个隐式原型对象,用__proto__代替。指向构造函数的显式原型对象,这个隐式原型对象也是一个对象对不对,所以隐式原型对象上也有__proto__隐式原型对象,
所以当我们查找一个对象的key对应的属性值的时候,对象本身没找到,会查找对象的隐式原型,隐式原型的隐式原型对象……这样层层查找的轨迹就是原型链。原型链总有尽头,那尽头是什么呢?就是Object对象的隐式原型对象,而它指向null,所以在代码中我们查找到原型对象的值为null的时候说明查找到了尽头。
我们知道对象可以通过原型链查找属性与方法,那在原型链上重写的方法就会被所有通过原型链继承的对象共享。

2-原型链实现继承

主要原理是让父类的实例对象作为子类构造函数的显式原型对象,这个父类实例对象的隐式原型指向的是自身构造函数的显式原型对象,这个显式原型对象的隐式原型对象指向的Object的原型对象。

  function Person() {

  }
  function Student() {

  }
  let p = new Person()
  Student.prototype = p
  let stu = new Student()
  console.log(stu.__proto__ == Student.prototype)//true
  console.log(Student.prototype == p)//true
  console.log(stu.__proto__ == p)//true
  console.log(p.__proto__ == Person.prototype)//true
  console.log(Person.prototype.__proto__)//Object对象
  console.log(Person.prototype.__proto__.__proto__)//null
  //Object.create方法,使用现有对象作为对象的原型
  let o = Object.create(p)
  console.log(o.__proto__ == p)//true

3-一些相关的方法

instanceof:检测某个构造函数的显式原型prototype是否在某个实例对象的原型链上
isPropertyOf:检测某个对象是否在某个对象的原型链上。
for in:遍历对象及其原型上的属性
hasOwnProperty:是否是对象自身的属性

Object.defineProperty

4-类class

class是构造函数和原型链的语法糖。所以操作一个类实际也就是操作本质上的构造函数。

使用new关键字的时候调用constructor函数的时候做了什么?

//改变隐式原型是为了继承,改变this指向是为了为原型对象挂载属性;
新建一个空对象,这个对象其实就是原型对象;
将这个对象隐式原型对象被赋值为构造函数也就是类的显式原型对象;
将构造函数内部的this指向这个对象;
然后是执行构造函数内的代码,大致就是挂载属性与方法到这个空对象中;
如果构造函数有传入的对象返回那个对象,如果没有其他对象就返回这个空对象。

  class Person {
    constructor(name, age) {
      //使用new关键字实例化类(实例化对象)的时候会自动调用这个函数
      //在这个函数主要做的是在原型对象上绑定共享属性与方法
      this.address = "南京"
      this.sex = "女"
      this.name = name
      this.age = age
    }
    //setter、getter方法
    set name(name) {
      console.log("调用了setter方法")
      this._name = name
    }
    get name() {
      console.log("调用了getter方法")
      return this._name
    }
    getAge() {
      return "年龄是:" + this.age
    }
    //静态方法
    static address() {
      return new Person("syc", 70)
    }
    //extends和super
  }
  let p = new Person("yyy", 20)
  console.log(p.name)//调用了setter和getter方法
  console.log(Person.address())
  class Student extends Person {
    constructor(name, age, classes) {
      //复用父类的构造函数需要super关键字
      super(name, age)
      this.classes = classes
    }
    getMessage() {
      return this.name + ":" + this.address + ":" + this.age + ":" + this.classes
    }
    getAge() {
      //调用父类方法需要用super
      return super.getAge()
    }
    static Ok() {
      //调用父类静态方法用super
      return super.address()
    }
  }
  let stu = new Student("zzz", 12, 1903)
  console.log(stu.getMessage())
  console.log(stu.getAge())
  console.log(Student.Ok())

继承还可以继承内置类比如Array等,对其内置方法进行修改,方便我们使用内置类;

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

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

相关文章

如何在华为OD机试中获得满分?Java实现【最佳对手】一文详解!

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Java华为OD机试真题(2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述4. Java算法源码5. 测试6.解题思路1. 题目描述 游戏里面,队伍通过匹配…

native层函数没有导出时,如何获得相应函数地址?

前言 每次App重新运行后native函数加载的绝对地址是会变化的,唯一不变的是函数相对于基地址的偏移,因此我们可以在获取模块的基地址后加上固定的偏移地址获取相应函数的地址,Frida中也正好提供了这种方式:先通过Module.findBaseA…

SQL教程1

SQL 是用于访问和处理数据库的标准的计算机语言。 在本教程中,您将学到如何使用 SQL 访问和处理数据系统中的数据,这类数据库包括:MySQL、SQL Server、Access、Oracle、Sybase、DB2 等等。 SQL 简介 SQL (Structured Query Language:结构化…

OSPF协议

OSPF:开放式最短路径优先协议 无类别IGP协议;链路状态型;基于LSA收敛,故更新量较大,为在中大型网络正常工作,需要进行结构化的部署 --- 区域划分、ip地址规划 组播更新 --- 224.0.0.5 224.0.0.6 支持等开销…

shell变量的使用 rhce(25)

目录 1.总结变量的类型及含义? 2.实现课堂案例计算长方形面积?(6种方式) 3.定义变量urlhttps://blog.csdn.net/weixin_45029822/article/details/103568815(通过多种方法实现) (1&#xff0…

Redis的数据过期策略

数据淘汰策略-使用建议 1.优先使用allkeys-lru策略。充分利用LRU算法的优势,把最近最常访问的数据留在缓存中。如果业务有明显的冷热数据区分,建议使用。 2.如果业务中数据访问频率差别不大,没有明显冷热数据区分,建议使用allkeys…

【AUTOSAR】 AUTOSAR整体开发流程(六)---- ISOLAR与Simuink

ISOLAR与Simuink交互 8.1 AutoSar的几种开发流程 8.2 Simulink 到ISOLAR Simulink生成SWC arxml SWC arxml放到ISOLAR文件夹 F5即可显示 8.3 ISOLAR到Simulink 1、Matlab的几个命令 1)importer Call the constructor arxml.importer to create an importer obj…

Nomad 会替代 Kubernetes 吗?对比一下,两者如何选择?

概 述 根据市场状况,Kubernetes(又称“K8s”)已经成为容器编排之王,超越了Docker Swarm和Mesos等竞争对手。但是,在K8s(2014)出现的同时,还有另一个编排项目HashiCorp的Nomad&…

同城跑腿系统源码,点对点配送,帮你省时省力

随着互联网的发展,越来越多的人开始依赖网络来解决生活中的各种问题。而同城跑腿系统就是其中一个受欢迎的解决方案。 ​同城跑腿系统是指一种基于互联网的服务,通过在线平台将用户和服务提供者连接起来,以便用户可以轻松地安排他们的日常任务…

Selenium Grid- 让自动化分布式执行变得可能

什么是 Selenium Grid? Selenium Grid 是 Selenium 的三大组件之一,允许用户同时在不同的机器和系统上测试不同浏览器。 也就是说 Selenium Grid 支持分布式的测试执行。它可以让你的测试用例在一个分布式的执行环境中运行。 由上图可见,测试…

Python之并发编程二多进程理论

一、什么是进程 进程:正在进行的一个过程或者说一个任务。而负责执行任务则是cpu。 二、进程与程序的区别 程序仅仅只是一堆代码而已,而进程指的是程序的运行过程。 三、并发与并行 无论是并行还是并发,在用户看来都是’同时’运行的&am…

从实际案例聊聊Java应用的GC优化

概 述 当Java程序的性能无法达到预期目标时,开发人员通常需要借助GC优化来进一步提高性能。然而,GC算法复杂,影响GC性能的参数众多,且参数调整又依赖于应用各自的特点,这些因素大大增加了GC优化的难度。不过&#xf…

GitLab 目录遍历漏洞复现(CVE-2023-2825)

0x01 产品简介 Gitlab是目前被广泛使用的基于git的开源代码管理平台, 基于Ruby on Rails构建, 主要针对软件开发过程中产生的代码和文档进行管理,同时可以搭建Web服务。 0x02 漏洞概述 GitLab 存在目录遍历漏洞,当嵌套在至少五个组中的公共项目中存在附…

demlia机器人建模与装配

1 可以用catia中的模型或其他三维建模软件中的模型转化为step格式即可 2 在demlia中打开 3 打开单个零件保存为cgr格式 对机械臂所有零件都做同样的转化 4 新建装配设计,并导入带有坐标的零件 将转化后的零件都选中导入即是装配好的 5 将模式修改为device buildin…

mysql超全语法大全

mysql安装教程 一、登录(使用可视化工具,可忽略) 打开命令行工具,输入以下命令,根据提示输入 root 用户的密码。 mysql -u root -p mysql -u root -p -D 数据库名二、创建数据库 显示数据库:SHOW DATAB…

Shell脚本攻略:条件语句if、case

目录 一、理论 1.条件测试 2.if语句 3.case语句 二、实验 1.实验一 2.实验二 3.实验三 4.实验四 5.实验五 6.实验六 7.实验七 一、理论 1.条件测试 (1)三种测试方法 ① test命令测试 ② [ ]测试(注意前后需要有空格&…

Java多线程编程

Java多线程编程 前言 Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。这里定义…

新快报:十年聚焦,巨杉数据库打造中国基础软件的“原创力”

广东省级主流媒体新快报策划“非凡十年,广州答卷”专题,关注十年来广州的“原创力量”,作为土生土长的广州基础软件创新企业,巨杉数据库十年聚焦,从零打造原生分布式数据库,获得逾百家金融银行客户认可&…

STM32——SDIO的学习(驱动SD卡)(实战篇)

目录 一、SDIO寄存器 1.1 SDIO电源控制寄存器(SDIO_POWER) 1.2 SDIO时钟控制寄存器(SDIO_CLKCR) 1.3 SDIO参数寄存器(SDIO_ARG) 1.4 SDIO命令寄存器(SDIO_CMD) 1.5 SDIO命令响应寄存器(SDIO_RESPCMD) 1.6 SDIO响应 1..4 寄存器(SDIO_RESPx) 1.7 SDIO数据定时器寄存器(S…

C语言程序设计题/C语言计算机二级考前押题版

C语言程序设计题/C语言计算机二级考试押题版 与 数位 和 数 有关 求max与min 任意四个数 运算符和表达式版本 #include <stdio.h> int main( ) {int a,b,c,d;int max,min;printf("please input 4 integers:");scanf("%d%d%d%d", &a, &b, …