深入浅出之JavaScript原型链

原型链可以说是JavaScript中非常重要的概念,但是其概念对于部分同学可能来说非常的抽象,为此本篇文章/笔记将深入浅出原型链,不再迷惑!

JavaScript中的原型链是一个非常有魔力的东西

javascript中,实例对象与原型之间的链接,叫做原型链。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。然后层层递进,就构成了实例与原型的链条,这就是所谓原型链的基本概念。[1]

Javascript

0x01 基本概念

首先先记住几个概念:

  1. 隐式原型:所有引用类型(函数、数组、对象)都有 __proto__ 属性,例如arr.__proto__
  2. 显式原型:所有函数拥有prototype属性,例如:func.prototype
  3. 原型对象:拥有prototype属性的对象,在定义函数时被创建

再理解一下prototype__proto__

  • js中所有的函数都有一个prototype的属性,该属性引用了一个对象,该对象叫做原型对象
  • js中每个对象都有一个__proto__属性,该属性指向它构造函数prototype

0x02 构造函数

上面的概念中提到了构造函数,那么什么是构造函数呐?

JavaScript 中,用 new 关键字来调用的函数,称为构造函数。构造函数首字母一般大写[2]

先看一个例子:

function Person() {}
var person = new Person()

第一行代码声明了一个名为 Person 的函数,第二行代码,根据上面的构造函数定义,那么函数 Person 可以称作一个构造函数

JavaScript 的内置对象(比如:ObjectArray)中,都是 Function 构造函数实例


0x03 prototype与proto的属性

规定 __proto__prototype的属性包括 __proto__constructor 两个

  • __proto__ 指向对象的构造函数的prototype
  • constructor指向对象的构造函数

在浏览器下的运行情况可以看到

实际情况

在上面的例子中person对象是 Person 构造函数的一个实例,那根据规定,下面的关系一定成立

person.__proto__ === Person.prototype     // output:true

person的构造函数是Person这个结论是正确的

在其中的概念可以看到__proto__中有__proto__,那么是不是就可以无限访问下去呐?那就会产生一个疑问,__proto__到最后是个啥?


0x04 原型链

通过上面的问题,自然就引入了“原型链”的概念,在这一条__proto__的链路上,最终所有都指向了Object

为了在整体上有一个清晰的概念,我做了一幅图

转载请注明作者DYBOY

小伙伴们可以仔细推敲一下这个图,是不是脑袋里清晰多啦,JavaScript皆对象!


0x04 原型链查找机制

知道了原型链,但还不知道原型链到底有什么用对吧?搞这么复杂,到底有啥用?

有用!一开始的描述当中,又看到“继承”这个关键词,对于熟悉了面向对象的小伙伴,没什么理解难度,入门小伙伴可以理解为“子承父业,青出于蓝而胜于蓝

过于抽象,举个栗子

不举了,emmm。。。

原型链里的查找机制:基于 __proto__ 向上搜索原则,例如,person实例对象没有eat方法,则向上查找person.__proto__其构造函数Personprototype中查找是否存在eat方法,如果存在,则直接调用,否则基于向上查找Object.prototype中是否存在eat方法,若也不存在,则返回undefined

搞定,开心到飞起!

奇怪的知识增加了_DYBOY


REFERENCE

[1] 什么是javascript原型链?
[2] JS构造函数理解

发表评论 / Comment

用心评论~

金玉良言 / Appraise
DYBOY站长已认证
2020-08-06 10:06
Polyfill 是一块代码(通常是 Web 上的 JavaScript),用来为旧浏览器提供它没有原生支持的较新的功能。
头像
是寒风丫LV 2
2020-08-09 12:27
@DYBOY:东哥,有推荐的不备案主机没
头像
DYBOY站长已认证
2020-08-10 00:39
@是寒风丫:国外主机或者云服务器都不需要备案,建议可以在国内,速度什么的都还是非常ok,而且个人博客备案也不算麻烦。如果不介意速度,可以用github搭建个人博客~
头像
是寒风丫LV 2
2020-08-14 19:41
@DYBOY:好的OK

Warning: Cannot modify header information - headers already sent by (output started at /www/wwwroot/blog.dyboy.cn/content/templates/dyblog/footer.php:56) in /www/wwwroot/blog.dyboy.cn/include/lib/view.php on line 23