原型和原型链的理解_JavaScript经典面试之原型与原型链图解(一)

b2bf08ea55ab5f23041c5c19a4b7cc60.png

1. 前言

原型与原型链是JavaScript中的核心概念之一,也是初学者的噩梦,同时面试时被问到的概率大概在80%以上!

通过这个问题,可以考察应聘者对JavaScript基础知识的理解与掌握程度。原型链的知识通过死记硬背是记不住的,就算今天记住,明天准忘了。

但是,当你真正理解原型链的概念之后,你会发现,原型链竟然如此简单,而且很难忘记。

最近两个月都在招人面试,面了有30+,不管对方是初级、高级还是资深级别,这道题必问。但是真正理解原型链的人不到3个。

很多人能够说准确说出原型链的概念,但是你让他针对具体的实例写出对应的原型链,能写对的人寥寥无几。

所以今天准备写一篇关于原型链的文章,和大家分享一下我对原型链的理解,如有错误的地方,欢迎大家探讨。

2. 原型与原型链的概念

我们来看一下MDN对原型与原型链的解释:

当谈到继承时, JavaScript 只有一种结构:对象。每个实例对象( object )都有一个私有属性(称之为 __proto__ )指向它的 构造函数的原型对象prototype)。该原型对象也有一个自己的原型对象( __proto__ ) ,层层向上直到一个对象的原型对象为 null。根据定义, null没有原型,并作为这个 原型链中的最后一个环节。

上面有个概念,我们务必记住:

  • 每个实例对象都有一个私有属性:__proto__ ,该私有属性 指向实例构造函数的原型对象。

3. 原型与原型链图解

所谓原型”“,不管是现实中的锁链,还是计算机算法中的链表,他们都是把一个一个节点串联起来,从而形成一条链。

在JavaScript中,原型链也是如此。原型对象是节点,而私有属性 __proto__ 就是串联连接两个原型对象节点的”线“。

例如,有一个超类(SupType)和子类(SubType),子类通过原型继承超类,并创建一个子类的实例对象 instance,具体代码如下:

function SupType() {
  this.supProperty = true;
  this.name = 'SupType';
}

SupType.prototype.getSupValue = function() {
  return this.supProperty;
}

function SubType() {
  this.subProperty = false;
}

SubType.prototype = new SupType();

SubType.prototype.constructor = SubType;

SubType.prototype.getSubValue = function() {
  return this.subProperty;
}

SubType.prototype.getName = function() {
  return this.name;
}

const instance = new SubType();

按照上面我们对“务必记住的概念”的理解,instance 对象的 __proto__ 指向实例(instance)构造函数原型对象:SubType.prototype,图解如下:

af87caf8d083d4c05988048cdf9e7430.png

SubType.prototype 是超类 SupType 的实例,也有一个 _proto 属性,所以SubType.prototype.__proto__指向 SubType.prototype 对象构造函数的原型对象:SupType.prototype,图解如下:

d9a3910f51ed49525cae2bf35422db6a.png

SupType.prototype 也有一个 __proto__ 属性,那 SupType.prototype 对象又是哪个构造函数的实例对象呢?

答案是 Object,所以 SupType.prototype.__proto__ 指向的是 Object.prototype 对象。那Object.prototype 又是哪个构造函数的实例对象呢?是 null 对象,无中生有,原型链的终点。

图解如下:

fbc52caf006ae14d6c11dff0082a2db3.png

用代码表达,这条原型链如下:

instance.__proto__ === SubType.prototype

SubType.prototype.__proto__ ==== SupType.prototype

SupType.prototype.__proto__ === Object.prototype

Object.prototype.__proto__ === null

4. 其他

在JavaScript中,引用类型和基本包装类型可以通过构造函数创建实例对象,这些实例的原型链与Object创建实例的原型链类似,最终也是指向 null 对象,原型链完整版图解如下:

737edaef81867f68cfda070999a5bd57.png

5. 总结

  • 每一个实例对象都有一个私有属性 __proto__ ,该私有属性总是指向实例构造函数的原型对象;
  • 不同的原型对象”节点“通过 __proto__ 指向进行串联连接,从而形成一条原型链。
  • 原型链的终点为 null 对象,即无中生有。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值