(原型与原型链)前端八股文修炼Day5

在这里插入图片描述

一 原型链的理解

  1. 原型链定义
    原型链是 JavaScript 中实现对象继承的关键机制之一,它是一种对象之间的关系,通过这种关系,一个对象可以继承另一个对象的属性和方法。

  2. 原型链的组成
    每个对象都有一个指向另一个对象的内部链接(-proto-),即原型对象。如果在当前对象上无法找到属性或方法,JavaScript 引擎会沿着原型链向上查找,直到找到对应的属性或方法。

  3. 原型对象和构造函数
    在 JavaScript 中,通过构造函数创建的对象实例会关联到构造函数的 prototype 属性指向的对象。这样,实例可以通过原型链访问构造函数的原型对象上定义的属性和方法。

  4. 顶端的原型
    所有对象的原型链的顶端是 Object.prototype,它是 JavaScript 中所有对象的基础原型,包含一些常用的方法(比如 toString()hasOwnProperty() 等)。

  5. 原型链的作用
    原型链使得对象之间可以共享属性和方法,实现了高效的代码复用和继承。通过原型链,我们可以更灵活地组织和扩展对象的功能。

  6. 示例解释
    举例说明原型链的作用和实现方式,比如创建一个自定义构造函数、定义其原型对象上的方法,以及如何通过原型链访问这些方法。例如:

  • prototype: 所有的函数类型天生都自带一个属性:prototype(原型),这个属性的值是一个对象 ,浏览器默认会给它开辟一个堆内存;
  • constructor: 在浏览器给prototype开辟的堆内存中有一个天生自带的属性:constructor,这个属性存储的值是当前的函数本身。
  • -proto-: 每一个对象都有一个_-proto-_的属性,这个属性指向当前实例所属类的prototype。如果不确定它是谁的实例,那么都为Object的实例。
  • 原型链机制:通过__proto__隐式原型链向上查找的机制;
  • 向上查找:当我们操作实例的某个属性或者方法的时候,首先找自己空间中私有的属性和方法;
    • 若找到,结束查找,使用自己私有的即可
    • 若没找到,则基于__proto__找所属类的prototype,如果找到就用共有的,如果没找到,基于原型上的__proto__进行查找,一直找到Object.prototype的原型为止,如果还是没有,操作的属性或者方法不存在。
      图解如下:
      在这里插入图片描述

二 原型修改

在 JavaScript 中,原型链的理解是非常重要的,特别是在处理对象继承和原型链修改时。让我来解释一下原型修改、重写原型链以及原型链指向的终点:

  1. 原型修改
    在 JavaScript 中,可以通过修改对象的原型对象来改变对象的行为。这意味着可以向原型对象添加新属性或方法,从而让所有基于该原型对象创建的实例都能访问到这些属性或方法。原型修改是一种扩展对象功能的有效方法。

  2. 重写原型链
    重写原型链指的是将一个对象的原型对象指向另一个对象,从而改变对象的原型链。这样做可以实现对象之间的继承关系重组,让一个对象继承另一个对象的属性和方法。

  3. 原型链的终点
    原型链的终点是指原型链的最顶层,即所有对象原型链的顶端都指向的对象。在 JavaScript 中,原型链的终点是 Object.prototype,它是所有对象的基础原型,包含一些通用的方法,比如 toString()hasOwnProperty() 等。

当我们访问一个对象的属性或方法时,JavaScript 引擎会沿着原型链向上查找,直到找到对应的属性或方法或者查找到达原型链的终点为止。如果在整个原型链中都找不到对应的属性或方法,操作就会失败。

通过修改原型对象或重写原型链,我们可以实现对象之间的继承和共享属性方法,从而达到增强对象功能的目的。同时,了解原型链的终点有助于我们理解 JavaScript 对象之间的关系以及属性方法的查找顺序。
继承的实现可参考

三 如何打出原型链的终点

要打印出原型链的终点,你可以使用以下代码来获取原型链终点所指向的对象:

function getPrototypeChainEnd(obj) {
    let currentObj = obj;
    
    while(Object.getPrototypeOf(currentObj) !== null) {
        currentObj = Object.getPrototypeOf(currentObj);
    }

    return currentObj;
}

// 示例:打印出原型链的终点
console.log(getPrototypeChainEnd(Object.prototype)); // 输出:Object {}

在这段代码中,getPrototypeChainEnd 函数接收一个对象作为参数,然后通过迭代查找对象的原型链,直到找到原型链的终点。最后,返回原型链的终点对象。

你可以替换 Object.prototype 为任何你想要查看原型链终点的对象。这段代码会帮助你打印出原型链的终点对象。希望这能解决你的问题!如果有任何其他问题,请随时告诉我。

四 如何获取非原型链上的属性

要获取对象自身拥有的属性(即非原型链上的属性),可以使用 Object.keys() 方法来获取对象的所有可枚举属性,然后过滤掉原型链上的属性。以下是一个简单的示例代码:

function getOwnProperties(obj) {
    return Object.keys(obj).filter(key => obj.hasOwnProperty(key));
}

// 示例:获取对象非原型链上的属性
const obj = {
    a: 1,
    b: 2
};

// 向原型添加属性
Object.prototype.c = 3;

const ownProperties = getOwnProperties(obj);
console.log(ownProperties); // 输出: ["a", "b"]

在这个示例中,getOwnProperties 函数接收一个对象作为参数,使用 Object.keys() 方法获取对象的所有属性名,然后通过 hasOwnProperty() 方法过滤掉原型链上的属性,最终返回对象自身拥有的属性名数组。

  • 11
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值