当前位置: 首页 > news >正文

前端八股之JS的原型链

1.原型的定义

每一个对象从被创建开始就和另一个对象关联,从另一个对象上继承其属性,这个另一个对象就是 原型

当访问一个对象的属性时,先在对象的本身找,找不到就去对象的原型上找,如果还是找不到,就去对象的原型(原型也是对象,也有它自己的原型)的原型上找,如此继续,直到找到为止,或者查找到最顶层的原型对象中也没有找到,就结束查找,返回undefined

这条由对象及其原型组成的链就叫做原型链。

总结:

  1. 原型存在的意义就是组成原型链:引用类型皆对象,每个对象都有原型,原型也是对象,也有它自己的原型,一层一层,组成原型链。
  2. 原型链存在的意义就是继承:访问对象属性时,在对象本身找不到,就在原型链上一层一层找。说白了就是一个对象可以访问其他对象的属性。
  3. 继承存在的意义就是属性共享:好处有二:一是代码重用,字面意思;二是可扩展,不同对象可能继承相同的属性,也可以定义只属于自己的属性。

2.原型链定义

每个对象都有一个内部属性 [[Prototype]](可通过 __proto__ 访问),这个[[Prototype]]指向它的原型对象(prototype),这个原型对象也有自己的 __proto__,一直向上查找,最终到达终点null,形成原型链

总结:

  1. 对象有__proto__属性,函数有__proto__属性,数组也有__proto__属性,只要是引用类型,就有__proto__属性,指向其原型。
  2. 只有函数有prototype属性,只有函数有prototype属性,只有函数有prototype属性,指向new操作符加调用该函数创建的对象实例的原型对象。

实例代码

function Person(name) {this.name = name;
}Person.prototype.sayHello = function() {console.log("Hello, I'm " + this.name);
};const p = new Person("Alice");p.sayHello(); // 从 p 找不到 sayHello,顺着原型链找到 Person.prototype

p --> Person.prototype --> Object.prototype --> null

  • p.__proto__ === Person.prototype

  • Person.prototype.__proto__ === Object.prototype

  • Object.prototype.__proto__ === null

3.constructor

构造函数都有一个prototype属性,指向使用这个构造函数创建的对象实例的原型对象

这个原型对象中默认有一个constructor属性,指回该构造函数。

Person.prototype.constructor === Person // true

4.应用

①.手写实现instanceof

function instanceof2(L, R) {// 获取 R 的 prototype.//R 是构造函数,我们要找的是它的 .prototype,这是构造出来对象的原型。let RP = R.prototype;// 获取 L 的原型//取 L 的原型(注意是 __proto__,而不是 prototype),它表示当前对象的内部原型链引用。L = L.__proto__;// 遍历 L 的原型链while (true) {if (L === null) { // 到头了都没找到,说明不是return false;}// 🔽 插入这行代码if (L === RP) {  // 找到了原型链中有构造函数的 prototypereturn true;}L = L.__proto__;  // 继续向上查找原型链}
}
  • instanceof 的本质:判断某对象的原型链上是否能找到构造函数的 .prototype
  • __proto__ 是对象的内部原型引用。

  • 可以用 Object.getPrototypeOf(obj) 来代替 __proto__(更标准)。

http://www.dtcms.com/a/231692.html

相关文章:

  • 项目实战——C语言扫雷游戏
  • MySQL ACID 面试深度解析:原理、实现与面试实战
  • SARIMA时间序列分析:三大模型对比
  • Python网页数据抓取常用的库及方法介绍
  • SpringBoot+Mybatisplus配置多数据源(超级简单!!!!)
  • C# 一个解决方案放一个dll项目,一个dll测试项目 ,调试dll项目的源码
  • NLP学习路线图(二十三):长短期记忆网络(LSTM)
  • BERT vs Rasa 如何选择 Hugging Face 与 Rasa 的区别 模型和智能体的区别
  • 祝贺XC3576H通过银河麒麟桌面操作系统的兼容性测试,取得麒麟软件互认证证书
  • tensorflow image_dataset_from_directory 训练数据集构建
  • 力扣刷题Day 70:在排序数组中查找元素的第一个和最后一个位置(34)
  • python3GUI--车牌、车牌颜色识别可视化系统 By:PyQt5(详细介绍)
  • 【更新至2024年】1991-2024年上市公司信息披露质量KV指数数据(含原始数据+计算过程+结果)
  • Vue跨层级通信
  • c++中char *p指针指向字符串输出问题
  • 2D 写实交互数字人:多终端实时交互,引领数字化浪潮
  • 软件工程:如何在项目中把软件做好
  • 数学复习笔记 25
  • 神经符号AI的企业应用:结合符号推理与深度学习的混合智能
  • 虚拟机CentOS 7 网络连接显示“以太网(ens33,被拔出)“、有线已拔出、CentOS7不显示网络图标
  • Redis中的setIfAbsent方法和execute
  • Mybatis入门到精通
  • SQL 中 JOIN 的执行顺序优化指南
  • GAN模式崩塌难题:成因分析与多维度解决方案
  • nlohmann/json简介及使用
  • 半导体热电技术方案领跑者「富信」×企企通,构建采购数字化升级
  • Cursor 工具项目构建指南:Java 21 环境下的 Spring Boot Prompt Rules 约束
  • psycopg2-binary、pgvector、 SQLAlchemy、 PostgreSQL四者的关系
  • .NET 原生驾驭 AI 新基建实战系列(三):Chroma ── 轻松构建智能应用的向量数据库
  • vue源码解析——diff算法