手机版

帮助你彻底理解JS中的原型 __proto__和构造函数(插图)

时间:2021-08-20 来源:互联网 编辑:宝哥软件园 浏览:

小贴士:不要排斥它,静下心来仔细阅读,你就会明白了!(可以先看最后的总结,再回去完整的看一遍)

1.前言

作为前端工程师,必须了解JS中的原型,_ _ prototype _ _和构造函数属性。相信很多初学者对这些属性比较困惑,容易混淆。本文旨在帮助你理清它们之间的关系,并彻底理解它们。这里需要注意的是__proto__属性的两边都是由两个下划线组成的(这里为了方便大家,在两个下划线之间加了一个空格:_ _proto_ _)。事实上,ES标准定义中的属性名称应该是[[Prototype]],具体实现是由浏览器代理自己实现的。谷歌浏览器的实现是放[[原型]]。本文基于谷歌浏览器(72.0.3626.121版)的实验结果。

现在正式开始了!让我们从下面一个简单的例子开始讨论,并用相关的图表帮助我们理解它:

function Foo(){ 0.};让f1=new Foo();上面的代码意味着创建一个构造函数Foo(),并用new关键字实例化该构造函数以获得一个实例化的对象f1。在这里,我想补充一下新运算符调用函数作为构造函数时的过程:函数被调用,然后创建一个新的对象,这个对象就成为函数的上下文(也就是函数内部的这个此时指向新创建的对象,这意味着我们可以通过构造函数内部的这个参数来初始化值),最后返回新对象的引用。虽然这是一个简单的两行代码,但它们背后的关系是复杂的,如下图所示:

看到这张图不要害怕,让我们一步一步分析,彻底了解他们!

图说明:图例在右下角,红色箭头表示__proto__属性指向,绿色箭头表示原型属性指向,棕色实心箭头表示自己的构造函数属性指向,棕色虚线箭头表示继承的构造函数属性指向。蓝色方块代表对象,浅绿色方块代表函数(这里,Foo()只代表函数,不代表执行Foo函数后的结果,图中其他函数相同)。图的中间部分是它们之间的连接,图的最左边部分是示例代码。

2._ _ proto _ _属性

首先需要牢记两点:__proto__和构造函数属性是对象独有的;原型属性是功能所独有的。但是由于JS中的函数也是一种对象,函数还具有__proto__和构造函数的属性,这也是我们混淆的一大原因。上图有点复杂。我们根据它的属性对它进行分离,然后对它进行分析:

首先,我们只在这里保留__proto__属性,它对于对象是唯一的。我们可以看到__proto__属性从一个对象指向一个对象,也就是指向它们的原型对象(也可以理解为父对象),那么这个属性的作用是什么呢?它的功能是在访问一个对象的属性时,寻找其__proto__属性所指向的对象(可以理解为父对象)。如果父对象没有这个属性,它将继续寻找它的__proto__属性所指向的对象(可以理解为祖父对象)。如果没有找到,还会继续往上走。),再往上查就相当于取null上的值,会报错(可以理解为再往上查就不再是“人”的范畴了,找不到了。在这一端,null是原型链的终点)。一个通过__proto__属性连接对象直到null的链就是我们所说的原型链。

3.原型属性

其次,接下来让我们看看原型属性:

别忘了,原型属性是我们之前提到的两点中的第二点,它是函数独有的,是从函数到对象的点。意思是一个函数的原型对象,也就是这个函数创建的一个实例的原型对象(其实所有的函数都可以作为构造函数)。因此,可以知道:f1。_ _ proto _ _==foo.prototype,它们完全一样。原型属性的作用是什么?它的功能是包含特定类型的所有实例都可以共享的属性和方法,也就是说,让这个函数实例化的对象找到通用的属性和方法。当创建任何函数时,默认情况下将同时创建该函数的原型对象。

4.构造函数属性

最后,让我们看看构造函数属性:

构造函数属性也属于对象,它从对象指向函数,这意味着它指向对象的构造函数。每个对象都有一个构造函数(它是自己拥有或继承的,结合__proto__来查看继承的属性会更清楚,如下图所示)。从上图可以看出,函数是一个特殊的对象。它的构造函数就是它自己(因为function可以看作是一个function或者一个object),所有的Functions和object最终都是从Function构造函数中派生出来的,所以构造函数属性的终点就是Function。

感谢网友们的指出,解释一下上一段“每个对象都有构造函数”这句话。这意味着每个对象都可以找到它对应的构造函数,因为创建对象的前提是要有一个构造函数,这个构造函数可以由对象本身明确定义,也可以通过__proto__在原型链中找到。只有原型对象具有构造函数属性。在创建每个函数时,JS会同时创建一个与该函数对应的原型对象,以及该函数创建的对象。__proto__===函数。原型,功能。prototype.constructor===函数本身,所以即使函数创建的对象没有构造函数属性,它也可以通过__proto__找到对应的构造函数,所以任何对象最终都可以找到它的构造函数(被视为对象的null除外)。如下所示:

5.摘要

总而言之:

我们需要记住两点:__proto__和构造函数属性对于对象是唯一的; prototype属性是函数独有的,因为函数也是对象,所以函数也有_ _ prototype _ _和构造函数属性。__proto__属性的作用是在访问对象的属性时,查看其__proto__属性所指向的对象(父对象),并一直查看,直到__proto__属性的结束点为空。查找相当于对null取一个值,这会报告一个错误。通过__proto__属性连接对象的链接称为原型链。prototype属性的作用是使这个函数实例化的对象找到共同的属性和方法,即f1。_ _ proto _ _==foo . prototype . constructor属性的含义是指向对象的构造函数,所有Functions(现在被认为是对象)的最终构造函数都指向function。本文到此结束,希望对那些对JS中的prototype、__proto__和构造函数属性感到困惑的同学有所帮助。

最后,我要感谢这两篇博客文章,其中一些引用自这两篇博客文章:https://www.jb51.net/article/168334.htm https://www.jb51.net/article/89523.htm.

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

版权声明:帮助你彻底理解JS中的原型 __proto__和构造函数(插图)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。