js深入之原型和原型链

本文详细探讨了JavaScript中原型的概念,原型链的工作原理,包括函数的prototype、__proto__的作用,以及constructor属性的指向。讲解了实例与原型间的关联,原型链的构成过程,并展示了原型在对象继承中的关键角色。
摘要由CSDN通过智能技术生成

js深入之原型和原型链

原型和原型链是我一直觉得自己理解但是并不是很深入的一个知识点,因为实际项目中用到的不多,所以一直没有机会深刻理解原型和原型链,在空闲时间学习并记录。

prototype

原型的概念是比较抽象的,在我起初的理解看来,它相当于一个最最基础的模型,我们可以根据原型实例化一个对象,也可以在之前的基础上修改原型。举例:

function Person(){
    
}
// 这里的prototype是函数才有的属性
Person.prototype.name = "小明";
let p1 = new Person();

我们打印一下实例p1

在这里插入图片描述

由此可以得出函数的prototype指向了一个对象,这个对象就是调用该构造函数创建的实例对象的原型,也就是p1的原型,此时如果我们再实例化一个对象p2,prototype也是指向p2的原型的,也因此prototype上绑定的属性和方法在实例间可以共享,也就是所说的“继承”属性。

__ proto __

prototype是函数特有的属性,表示构造函数和实例原型的关系,那我们应该如何表示实例和实例原型关联呢? 这个时候就需要使用到__ proto __ 这个属性。

在创建一个JavaScript对象的时候,每个对象都会有一个__ proto __ 的属性,该属性指向该对象的原型,此时注意。null类型没有 __ proto __ 这个属性

举例:当一个属性为null的时候,打印 a.__ proto __ 会报错

在这里插入图片描述

既然这个属性是每一个对象都有的,我们不妨打印一下实例的__ proto __ 与 构造函数的prototype,发现两个打印的结果是一致的。 都指向了实例的原型。

在这里插入图片描述

构造函数的prototype ——> 指向实例的原型,

实例化的__ proto __ ——> 指向实例的原型,

由此得出 构造函数 和 实例化对象都可以指向原型,那么原型是否有属性可以指向实例化对象或者构造函数呢??

constructor

首先考虑实例化对象的构造函数是什么?

实例化对象是根据构造函数生成的,一个构造函数可以生成多个实例对象,因此原型是没有属性指向实例对象的,但是有一个属性可以指向构造函数,那就是constructor,每一个原型都有一个constructor属性指向该原型所关联的构造函数,开始验证:

function Person(){
    
}
console.log(Person.prototype.constructor)// 打印一下结果
f Person(){ }
// Person.prototype 原型  
console.log(Person.prototype.constructor === Person); // true
// 同理的 p1.__proto__.constructor === Person 也是true

以上就是 构造函数实例原型 以及 实例 的概念和它们之间的关系。

实例与原型

当想要访问实例的属性时,如果在实例中找不到,就回去实例所关联的原型中的属性去寻找,也就是在prototype上绑定的属性,如果还是找不到,就去找原型所对应的原型,一直找到最顶层为止。

举个栗子:

function Person(){
    
}
Person.prototype.name = "小明"let person = new Person();
person.name = "小红";
console.log(person.name);  //此时打印的是小红

delete person.name;
console.log(person.name);  // 此时打印的就是 "小明"

// 在实例对象中找不到属性,就会去对应的 person.__proto__ 上也就是原型去寻找,也就是去Person.prototype寻找

上述情况在实例所关联的原型上找到了对应的属性,如果没有找到呢?如果原型上存在原型是要继续向上找的,那原型的原型又是什么呢?

原型链

原型链可以用一个关系直观的表示,就是:子类 ——> 父类 ——> 父类 ——> 父类…一直到最顶层。
由上面的打印结果可知,原型的本质其实是一个对象,是通过new Object()去生成的。那Object的原型又是什么呢? 我们可以打印一下:
在这里插入图片描述
打印的结果是null,表示Object没有原型,也就是说Object是原型链的最顶端。所以当我们在原型链上查找属性或者方法的时候,找到Object.prototype之后就会停止查找。这个查找的过程就会创建一个原型链。

最后

prototype的使用场景: 我们可以在自定义对象上绑定公用的方法或属性,也可以在自带的对象(如Array)上绑定我们的自定义方法。

__ proto :在构成原型链的过程中,需要使用到 proto __,一般不需要我们手动操作,事实上它不存在于Person.prototype中,而是在Object.prototype上,它相当于是一个getter/setter的过程,它返回了一个 Object.getPrototype(obj)。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值