鲁慧敏 發表於 2021-8-9 11:24:00

一张图带你搞懂Javascript原型链关系

<section id="nice" data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-size: 16px; padding: 0 10px; word-spacing: 0; word-wrap: break-word; text-align: left; line-height: 1.75; color: rgba(89, 89, 89, 1); font-family: Optima-Regular, Optima, PingFangTC-Light, PingFangSC-light, PingFangTC-light; letter-spacing: 2px; background-image: linear-gradient(90deg, rgba(50, 0, 0, 0.05) 3%, rgba(0, 0, 0, 0) 3%), linear-gradient(360deg, rgba(50, 0, 0, 0.05) 3%, rgba(0, 0, 0, 0) 3%); background-size: 20px 20px; background-position: center"><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">在某天,我听了一个老师的公开课,一张图搞懂了原型链。
<img src="https://img.soogif.com/ZpbNCYOJvp7NwQT2Iy2tldT1fsUD66GL.gif?scope=mdnice" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">老师花两天时间理解、整理的,他讲了两个小时我们当时就听懂了。<br>
<img src="https://img.soogif.com/lZ9uJfw8Vl1Qq8NL4hjRcTSMJoqf2amM.gif?scope=mdnice" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain">
今天我把他整理出来,分享给大家。也让我自己巩固加深一下。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">就是这张图:</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628476887665-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">为了更好的图文对照,我为每条线编了标号,接下来的细节讲解,都会用到这张图里的编号:
<img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628476829364-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">为了你更好的对照阅读,你可以单独打开这张图片,然后对比着文章看。
<img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628476847476-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain">
当然,我后边也会贴心的把对应区域截小图贴在文案附近。</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628476915047-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<h1 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 25px; text-align: center; border: 2px dotted rgba(172, 144, 206, 1); border-radius: 6px; background: rgba(222, 198, 251, 1)"><span class="prefix" style="display: none"></span><span class="content" style="display: inline-block; font-weight: bold; color: rgba(89, 89, 89, 1)">前置知识</span><span class="suffix"></span></h1>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">在对这张图进行详细拆解前,我们先来说几个前置的基础知识。以便后续更好的理解。
<img src="https://img.soogif.com/omylEn3il6DdmZnzGppTwKrkCn0PNrXz.gif?scope=mdnice" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></p>
<ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; font-size: 15px; color: rgba(89, 89, 89, 1); list-style-type: circle">
<li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">Function、Object、Array、String、Symbol等这些都是JavaScript的内建函数,也叫原生函数(js创造时,他们就存在的,是js内部提供的)</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">prototype:原型对象;</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">__proto__:隐式原型、对象的私有属性;</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">所有的函数都是Function构造出来的,包括Object等原生函数。可以说,每个函数都是Function类型的实例。</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">函数实际上是对象,但比较特殊,我们叫做函数对象</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">每个函数被创造出来时都有一个prototype,表示该函数的原型。他就是原型对象</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">每个对象身上都有一个私有属性__proto__,指向该对象的构造函数的原型对象。函数作为对象也有__proto__</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">prototype是一个对象,由Object构造出来的。所以他身上也有__proto__,永远指向对象的构造函数Object的原型(即:Object.prototype)</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">函数都是被Function构造出来的,所以每个函数的__proto__都指向Function的原型(即:Function.prototype)</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">Object.prototype的__proto__不能再指向自身无限循环,所以指向null</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">Function.__proto__指向自身原型。因为Function没人构造,“生下来”就有。</section></li></ul>
<hr data-tool="mdnice编辑器" style="margin: 10px 0; height: 1px; padding: 0; border-top: 2px solid rgba(217, 184, 250, 1); border-right: none; border-bottom: none; border-left: none">
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">如下图:<br>
函数a,既有prototype、也有__proto__</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477093268-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">内建函数Object,既有prototype、也有__proto__</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477101834-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">对象身上就只有__proto__</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477110941-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<h1 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 25px; text-align: center; border: 2px dotted rgba(172, 144, 206, 1); border-radius: 6px; background: rgba(222, 198, 251, 1)"><span class="prefix" style="display: none"></span><span class="content" style="display: inline-block; font-weight: bold; color: rgba(89, 89, 89, 1)">口诀提炼</span><span class="suffix"></span></h1>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">为了更好的掌握,我把相关的知识点汇总成下列几条口诀。接下来的剖析中都会用到。</p>
<ol data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; list-style-type: decimal; font-size: 15px; color: rgba(89, 89, 89, 1)">
<li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">函数是Function构造出来的</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">一切函数都是对象</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">只要是函数对象,就会有原型prototype和隐式原型__proto__两个属性。</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">普通对象身上只有__proto__,没有prototype</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">实例化对象的__proto__都指向构造函数的prototype</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">所有函数的prototype都指向自身prototype</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">所有prototype的__proto__都指向Object.prototype(Object的除外)</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">所有函数对象的__proto__都指向Function.prototype(包括Function自身)</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">对象身上都有constructor指向函数自身</section></li></ol>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px"><strong style="color: rgba(255, 0, 0, 1); font-weight: bold">注意:这里不考虑原型链指向修改、Object.create(null)这些特殊情况</strong></p>
<h1 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 25px; text-align: center; border: 2px dotted rgba(172, 144, 206, 1); border-radius: 6px; background: rgba(222, 198, 251, 1)"><span class="prefix" style="display: none"></span><span class="content" style="display: inline-block; font-weight: bold; color: rgba(89, 89, 89, 1)">剖析一张图</span><span class="suffix"></span></h1>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">接下来我们根据基础知识和口诀,正式来看图中的每一个细节</p>
<h2 data-tool="mdnice编辑器" style="margin: 20px 10px 0 0; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 22px; text-align: left"><span class="prefix" style="display: none"></span><span class="content" style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">图例:</span><span class="suffix"></span></h2>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">观察一个图之前,我们先看他的图例</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477155684-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<h4 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; color: rgba(0, 0, 0, 1); font-size: 14px; font-weight: bold"><span class="prefix" style="display: none"></span><span class="content" style="color: rgba(172, 144, 206, 1)">右边表示节点的类型:</span><span class="suffix" style="display: none"></span></h4>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">绿色方块:表示普通对象,比如平时创建的对象obj <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">{}</strong>、arr **[]**等<br>
红色方块:表示函数对象,也就是函数。他是一种特殊的对象。</p>
<h4 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; color: rgba(0, 0, 0, 1); font-size: 14px; font-weight: bold"><span class="prefix" style="display: none"></span><span class="content" style="color: rgba(172, 144, 206, 1)">左边表示箭头的指向:</span><span class="suffix" style="display: none"></span></h4>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">绿色箭头:表示用 new + 构造函数调用 的方式创建实例化对象<br>
白色箭头:表示当前节点的prototype原型对象的指向<br>
蓝色箭头:表示当前节点的__proto__私有属性的指向</p>
<h2 data-tool="mdnice编辑器" style="margin: 20px 10px 0 0; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 22px; text-align: left"><span class="prefix" style="display: none"></span><span class="content" style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">详情</span><span class="suffix"></span></h2>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; color: rgba(0, 0, 0, 1); font-size: 16px; font-weight: bold"><span class="prefix" style="display: none"></span><span class="content" style="border-bottom: 3px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">Function</span><span class="suffix" style="display: none"></span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">我们先看最右边的<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Function</strong>(图中色块1)。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">他是js的内部函数,你打印Function会得到标示着“本地代码”的结果。</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477189633-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">也就是说他是js一开始就有的。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">而伴随他出生的就是他的原型: <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Function.prototype</strong>。(图中色块2)<br>
prototype是函数特有的标志,每个函数被创建出来,身上就有一个prototype的属性,表示自己的原型对象。<br>
根据口诀:<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">所有函数的prototype都指向自身prototype。</strong><br>
也就是说,Function.prototype指向Function原型。<br>
所以 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Function.prototype === Function.prototype</strong>(图中线条a)</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477266588-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">然后说下比较特殊的<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Function.__proto__</strong></p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">因为Function他是个函数,函数又是一种特殊的对象(函数类对象,又叫函数对象)。所以作为对象身上特有的标志__proto__,在Function身上也有一个。<br>
另外,任何对象都可以理解为实例化对象,所以我们总结出口诀:<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">实例化对象的__proto__都指向构造函数的prototype</strong>、<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">所有prototype的__proto__都指向Object.prototype(Object的除外)</strong><br>
如:</p>
<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px"><code class="hljs" style="overflow-x: auto; padding: 16px; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0; font-size: 12px; -webkit-overflow-scrolling: touch"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;obj&nbsp;=&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">new</span>&nbsp;<span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">Object</span>()&nbsp;<span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;或&nbsp;const&nbsp;obj&nbsp;=&nbsp;{}&nbsp;的字面量写法</span><br><br>obj.__proto__&nbsp;===&nbsp;<span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">Object</span>.prototype&nbsp;<span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;true</span><br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;实例化对象obj,其隐式原型__proto__指向构造函数Object的原型</span><br></code></pre>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">所以,Function.__proto__<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">本来也应该</strong>指向Function的构造函数的原型。<br>
但是因为Function比较特殊,他是祖宗级别的函数,是JS中万物开天辟地就有的,不能说谁把他构造出来的,<br>
因此Function的__proto__的指向就比较特殊,他没有自己的构造函数,于是就指向了自己的原型。<br>
于是Function.__proto__指向自己的原型Function.prototype。<br>
所以 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Function.__proto__ === Function.prototype</strong>(图中线条b)</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477321142-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">这是原型链中第一个<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">特殊点</strong>。<br>
口诀:<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">所有函数对象的__proto__都指向Function.prototype(包括Function自身)</strong></p>
<h4 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; color: rgba(0, 0, 0, 1); font-size: 14px; font-weight: bold"><span class="prefix" style="display: none"></span><span class="content" style="color: rgba(172, 144, 206, 1)">扩展:</span><span class="suffix" style="display: none"></span></h4>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">原型对象prototype身上都有constructor属性,指回构造函数自身。<br>
所以 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Function.prototype.constructor === Function</strong></p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477344557-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; color: rgba(0, 0, 0, 1); font-size: 16px; font-weight: bold"><span class="prefix" style="display: none"></span><span class="content" style="border-bottom: 3px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">Object</span><span class="suffix" style="display: none"></span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">再说<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Object。(图中色块3)</strong><br>
我们平时见过这种创建函数的书写形式:</p>
<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px"><code class="hljs" style="overflow-x: auto; padding: 16px; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0; font-size: 12px; -webkit-overflow-scrolling: touch"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;obj&nbsp;=&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">new</span>&nbsp;<span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">Object</span>()<br></code></pre>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">可见Object是一个函数。但同时函数又是一个对象。所以Object就是一个函数对象。<br>
<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">只要是函数对象,就会有原型prototype和隐式原型__proto__两个属性。</strong></p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">我们先看<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Object.prototype</strong>。(图中色块4)<br>
Object作为一个函数,他就有自己的原型:Object.prototype。<br>
根据口诀:<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">所有函数的prototype都指向自身prototype</strong>:<br>
所以 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Object.prototype === Object.prototype</strong>(图中线条d)</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477356408-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">而对于<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Object.__proto__</strong> 我们可以这样理解:<br>
Object作为一个函数,他是Function构造出来的。形似下面这种写法:(图中线条c)</p>
<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px"><code class="hljs" style="overflow-x: auto; padding: 16px; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0; font-size: 12px; -webkit-overflow-scrolling: touch"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;<span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">Object</span>&nbsp;=&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">new</span>&nbsp;<span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">Function</span>()<br></code></pre>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">因此可以说Object是实例化函数对象。<br>
根据口诀:一切 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">实例化对象的__proto__都指向构造函数的prototype</strong> 、 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">函数是Function构造出来的</strong><br>
所以 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Object.__proto__ === Function.prototype</strong>。(图中线条f)</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477366048-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; color: rgba(0, 0, 0, 1); font-size: 16px; font-weight: bold"><span class="prefix" style="display: none"></span><span class="content" style="border-bottom: 3px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">原型的原型</span><span class="suffix" style="display: none"></span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">我们来分析下两个内置函数的原型的原型:</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">先看<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Function.prototype.__proto__</strong><br>
Function.prototype作为Function的原型对象,他就是一个普通对象,但凡普通对象就都是Object构造出来的,<br>
根据口诀:<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">实例化对象的__proto__都指向构造函数的prototype</strong>、<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">所有prototype的__proto__都指向Object.prototype(Object的除外)</strong><br>
所以所有prototype对象的__proto__都指向构造函数Object的原型。包括Function函数的原型的隐式原型,也指向Object的原型。<br>
所以 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Function.prototype.__proto__ === Object.prototype</strong>。(图中线条g)</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477375026-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">再看<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Object.prototype.__proto__</strong><br>
Object.prototype作为是一个普通对象,他的隐式原型__proto__也本应该指向构造函数的原型。<br>
但由于prototype对象都是Object函数构造的,按照上边的规则,Object.prototype.__proto__也本应该指向Object.prototype。但是这么死循环的指没完没了了不是,还没有意义。<br>
所以这里是原型链中第二个<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">特殊点</strong>:让Object.prototype的原型指向null,好结束这段轮回。<br>
也就是 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Object.prototype.__proto__ === null</strong>。(图中线条e)</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">口诀:<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">所有prototype的__proto__都指向Object.prototype(Object的除外)</strong></p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477386418-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">好在,Object.prototye的构造函数还是诚实的,知道自己的祖宗是谁,于是他的constructor属性还是Ojbect。<br>
<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Object.prototype.constructor === Object</strong></p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477416844-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; color: rgba(0, 0, 0, 1); font-size: 16px; font-weight: bold"><span class="prefix" style="display: none"></span><span class="content" style="border-bottom: 3px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">自定义函数</span><span class="suffix" style="display: none"></span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">我们都知道,平时我们用字面量的形式创建一个对象、数组、function,<br>
其实都是new Object()、或 new Array()、new Function 这样的形式创建的。(图中线条h)</p>
<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px"><code class="hljs" style="overflow-x: auto; padding: 16px; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0; font-size: 12px; -webkit-overflow-scrolling: touch"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">var</span>&nbsp;obj&nbsp;=&nbsp;{};&nbsp;&nbsp;<span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;类似写法&nbsp;var&nbsp;obj&nbsp;=&nbsp;new&nbsp;Object();</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">var</span>&nbsp;arr&nbsp;=&nbsp;[];&nbsp;&nbsp;<span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;类似写法&nbsp;var&nbsp;arr&nbsp;=&nbsp;new&nbsp;Array();</span><br><span class="hljs-function" style="line-height: 26px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">function</span>&nbsp;<span class="hljs-title" style="color: rgba(153, 0, 0, 1); font-weight: bold; line-height: 26px">Person</span>(<span class="hljs-params" style="line-height: 26px"></span>)&nbsp;</span>{}&nbsp;&nbsp;<span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;类似写法&nbsp;var&nbsp;Person&nbsp;=&nbsp;new&nbsp;Function(){}</span><br></code></pre>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">所以对象、数组、函数这些都是实例化对象。<br>
对象、数组稍后再谈,他们就是自定义对象。(图中色块7)<br>
先说我们创建的函数 — — <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">自定义函数</strong>。(图中色块5)</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">「自定义函数」和Object性质一样,都是函数对象。只不过自定义函数的名字是我们用户自定义的,比如Person、Animal、clickHandle等。而Object、Array等是JS内部原生提供的。<br>
但记住口诀:<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">只要是函数对象,就会有原型prototype和隐式原型__proto__两个属性</strong>。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">先说<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">自定义函数.prototype</strong>(图中色块6)。<br>
前边说过,<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">所有函数的prototype都指向自身prototype</strong>,原型上边的constructor再指回函数自身。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">所以 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">Person.prototype === Person.prototype</strong>(图中线条i)</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477429987-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">再说<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">自定义函数.prototype.__proto__</strong><br>
自定义函数的原型作为普通对象,由Object构造出来,其原型__proto__肯定指向Object.prototype。原理同Function.prototype。<br>
根据口诀:<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">实例化对象的__proto__都指向构造函数的prototype</strong>、<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">所有prototype的__proto__都指向Object.prototype(Object的除外)</strong><br>
所以 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">自定义函数.prototype.__proto__ === Object.prototype</strong>。(图中线条J)</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477451373-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">再说<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">自定义函数.__proto__</strong><br>
根据口诀:<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">实例化对象的__proto__都指向构造函数的prototype</strong><br>
因此,实例化对象(这里的自定义函数)的__proto__就指向构造函数的原型。根据口诀:<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">函数是Function构造出来的、所有函数对象的__proto__都指向Function.prototype(包括Function自身)</strong>。所有自定义函数的构造函数是Function,他的原型也就是右边的Function.prototype。<br>
<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">自定义函数.__proto__ === Function.prototype</strong>。(图中线条k)</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477461920-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; color: rgba(0, 0, 0, 1); font-size: 16px; font-weight: bold"><span class="prefix" style="display: none"></span><span class="content" style="border-bottom: 3px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">自定义对象</span><span class="suffix" style="display: none"></span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">说清楚了自定义函数,我们再来说<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">自定义对象</strong>。(图中色块7)<br>
比如obj、arr这样的对象,他们和我们平时“new + 构造函数()”得到的实例化对象一样:(图中线条L)</p>
<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px"><code class="hljs" style="overflow-x: auto; padding: 16px; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0; font-size: 12px; -webkit-overflow-scrolling: touch"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;object&nbsp;=&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">new</span>&nbsp;<span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">Object</span>()<br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;person&nbsp;=&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">new</span>&nbsp;Person()<br></code></pre>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">以这个person为例,说一下图中绿色块7:自定义对象</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">既然叫「自定义对象」,那他肯定就只是一个对象。<br>
对象就好说了,<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">普通对象身上只有__proto__,而且普通对象(实例化对象)的__proto__指向构造函数的prototype。</strong><br>
根据口诀:<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">实例化对象的__proto__指向构造函数的prototype</strong><br>
即自定义对象.__proto__ 指向 自定义对象的构造函数(即自定义函数)的prototype<br>
所以 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">person.__proto__ === Person.prototype</strong>。(图中线条m)</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">于是图中(实例化)自定义对象.__proto__ 指向了上边自定义函数原型。</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477489207-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">至此,这张图我们都过了一遍。</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477506174-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<h1 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 25px; text-align: center; border: 2px dotted rgba(172, 144, 206, 1); border-radius: 6px; background: rgba(222, 198, 251, 1)"><span class="prefix" style="display: none"></span><span class="content" style="display: inline-block; font-weight: bold; color: rgba(89, 89, 89, 1)">总结</span><span class="suffix"></span></h1>
<ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; font-size: 15px; color: rgba(89, 89, 89, 1); list-style-type: circle">
<li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">Function.__proto__ === Function.prototype【特殊】</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">Function.prototype === Function.prototype</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">Function.prototype.constructor=== Function</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">Function.prototype.__proto__ === Object.prototype</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">Object.__proto__ === Function.prototype。</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">Object.prototype.__proto__ === null 【特殊】</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">Person.__proto__ === Function.prototype</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">Person.prototype.__proto__ === Object.prototype</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">person.__proto__ === Person.prototype</section></li></ul>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; color: rgba(0, 0, 0, 1); font-size: 16px; font-weight: bold"><span class="prefix" style="display: none"></span><span class="content" style="border-bottom: 3px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">原型链</span><span class="suffix" style="display: none"></span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">由于原型对象prototype本身是一个对象,因此,他也有隐式原型__proto__。隐式原型指向的规则不变,指向构造函数的原型;<br>
这样一来,原型 -&gt; 隐式原型、隐式原型 -&gt; 原型。<br>
从某个对象出发,依次寻找隐式原型的指向,将形成一个链条,该链条叫做<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">原型链</strong>。<br>
在查找对象成员时,若对象本身没有该成员,则会到原型链中查找。</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477526844-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">在上图和知识总结中我们看到:<br>
自定义对象的__proto__指向自定义函数的原型。<br>
而自定义函数的原型也是一个对象,他虽然在函数一生下来就有了,但是他作为对象,也是Object函数对象构建的。因此自定义函数原型身上的__proto__指向Object的原型对象。<br>
而Object.prototype又指向null。<br>
观察发现这最左边的一条居然形成了一个链式指向:<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">自定义对象 -&gt; 自定义函数的原型 -&gt; Object原型 -&gt; null</strong>。<br>
当我们在最低部的自定义对象身上寻找一个属性或方法找不到的时候,JS就会沿着这条原型链向上查找,若找到就返回,<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">直到null还查不到就返回undefined</strong>。</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477536893-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">同样的,<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">函数 -&gt; Function原型 -&gt; Object原型 -&gt; null</strong>, 也形成了原型链。当我们在函数身上调用一个方法或属性时,根据原型链的查找规则,会一直层层向上查找到null。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">这也就是为什么,call、apply、bind这些函数是定义在Function原型身上的,我们也能用Person.call、Person.apply这样调用;hasOwnProperty、isPrototypeOf这些函数是定义在Object原型身上的,我们也能用Person.isPrototypeOf、obj.hasOwnProperty这样使用了。</p>
<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px"><code class="hljs" style="overflow-x: auto; padding: 16px; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0; font-size: 12px; -webkit-overflow-scrolling: touch"><span class="hljs-function" style="line-height: 26px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">function</span>&nbsp;<span class="hljs-title" style="color: rgba(153, 0, 0, 1); font-weight: bold; line-height: 26px">Person</span>(<span class="hljs-params" style="line-height: 26px"></span>)&nbsp;</span>{<br>&nbsp;&nbsp;<span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">'我是Person函数'</span>);<br>}<br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">let</span>&nbsp;obj&nbsp;=&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">new</span>&nbsp;<span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">Object</span>()<br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">let</span>&nbsp;person&nbsp;=&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">new</span>&nbsp;Person()<br><br><span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(person.hasOwnProperty(<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">'a'</span>));&nbsp;<br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;原型链查找:person&nbsp;-&gt;&nbsp;person.__proto__(即Person.prototype)&nbsp;-&gt;&nbsp;Person.prototype.__proto__&nbsp;(即Object.prototype)&nbsp;找到hasOwnProperty函数,执行调用</span><br><span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(Person.call());<br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;原型链查找:Person&nbsp;-&gt;&nbsp;Person.__proto__(即Function.prototype)&nbsp;找到call函数,执行调用</span><br><span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(obj.xxx)<br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;原型链查找:obj&nbsp;-&gt;&nbsp;obj.__proto__(即&nbsp;Object.prototype)&nbsp;-&gt;&nbsp;null&nbsp;没找到,返回undefined</span><br></code></pre>
<h1 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 25px; text-align: center; border: 2px dotted rgba(172, 144, 206, 1); border-radius: 6px; background: rgba(222, 198, 251, 1)"><span class="prefix" style="display: none"></span><span class="content" style="display: inline-block; font-weight: bold; color: rgba(89, 89, 89, 1)">知识点扩展</span><span class="suffix"></span></h1>
<h2 data-tool="mdnice编辑器" style="margin: 20px 10px 0 0; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 22px; text-align: left"><span class="prefix" style="display: none"></span><span class="content" style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">函数对象和普通对象</span><span class="suffix"></span></h2>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">普通对象是通过 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">new 函数()</strong> 创建/构造的<br>
函数对象是通过 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">new Function()</strong> 构造的</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477560103-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">所有对象都是通过 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">new 函数()</strong> 的方式创建的</p>
<ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; font-size: 15px; color: rgba(89, 89, 89, 1); list-style-type: circle">
<li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">该函数叫做构造函数;</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">创建的对象被称作实例化对象</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">对象赋值给变量后,变量中保存的是地址,地址指向对象所在的内存。</section></li></ul>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">函数也是一个对象,他是通过 <strong style="color: rgba(255, 0, 0, 1); font-weight: bold">new Function()</strong> 创建的
<img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628478223734-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></p>
<h2 data-tool="mdnice编辑器" style="margin: 20px 10px 0 0; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 22px; text-align: left"><span class="prefix" style="display: none"></span><span class="content" style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">原型对象 prototype</span><span class="suffix"></span></h2>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">原型prototype的本质:对象。<br>
prototype又称作原型对象。<br>
<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">原型对象也有一个自己的原型对象:__proto__</strong><br>
所有的函数都有原型属性prototype<br>
默认情况下,prototype是一个Object对象。也就是说由Object构造函数创建,其原型指向Object的prototype。<br>
prototype中默认包含一个属性:constructor,该属性指向函数对象本身<br>
prototype中默认包含一个属性:__proto__,该属性指向构造函数的原型(默认情况是Object.prototype)</p>
<h2 data-tool="mdnice编辑器" style="margin: 20px 10px 0 0; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 22px; text-align: left"><span class="prefix" style="display: none"></span><span class="content" style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">隐式原型 __proto__</span><span class="suffix"></span></h2>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">所有的对象都有隐式原型:__proto__属性<br>
隐式原型是一个对象,指向创建该对象的构造函数的原型 prototype<br>
在查找对象成员时,若对象本身没有该成员,则会到隐式原型中查找。<br>
层层向上知道Object.prototype。若到null还找不到则返回undefined。</p>
<blockquote class="multiquote-1" data-tool="mdnice编辑器" style="display: block; font-size: 0.9em; overflow: auto; overflow-scrolling: touch; padding: 10px 10px 10px 20px; margin-bottom: 20px; margin-top: 20px; text-size-adjust: 100%; line-height: 1.55em; font-weight: 400; border-radius: 6px; color: rgba(89, 89, 89, 1); font-style: normal; text-align: left; box-sizing: inherit; border: 1px solid rgba(222, 198, 251, 1); background: rgba(246, 238, 255, 1)"><span style="color: rgba(222, 198, 251, 1); font-size: 34px; line-height: 1; font-weight: 700">❝</span>
<p style="padding-top: 8px; padding-bottom: 8px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px; margin: 0; line-height: 26px; color: rgba(89, 89, 89, 1)"><strong style="color: rgba(255, 0, 0, 1); font-weight: bold">__proto__</strong> 并不是语言本身的特性,这是各大厂商具体实现时添加的私有属性,虽然目前很多现代浏览器的 JS 引擎中都提供了这个私有属性,但依旧不建议在生产中使用该属性,避免对环境产生依赖。生产环境中,我们可以使用 Object.getPrototypeOf 方法来获取实例对象的原型,然后再来为原型添加方法/属性。<br>
来自《es6》&lt;http://es6.ruanyifeng.com/#docs/class&gt;</p>
<span style="float: right; color: rgba(222, 198, 251, 1)">❞</span></blockquote>
<h2 data-tool="mdnice编辑器" style="margin: 20px 10px 0 0; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 22px; text-align: left"><span class="prefix" style="display: none"></span><span class="content" style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">隐式原型和原型出现的根本原因:</span><span class="suffix"></span></h2>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">js没有记录类型的元数据。因此,js只能通过对象的隐式原型找到创建他的函数的原型,从而确定其类型。</p>
<h2 data-tool="mdnice编辑器" style="margin: 20px 10px 0 0; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 22px; text-align: left"><span class="prefix" style="display: none"></span><span class="content" style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">特殊的两个情况</span><span class="suffix"></span></h2>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">Function的隐式原型指向自己的原型<br>
Object原型的隐式原型指向null</p>
<h2 data-tool="mdnice编辑器" style="margin: 20px 10px 0 0; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 22px; text-align: left"><span class="prefix" style="display: none"></span><span class="content" style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">两个固定情况</span><span class="suffix"></span></h2>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">所有函数的隐式原型,都指向Function的原型(包括Function函数自身)<br>
所有函数原型的隐式原型,都指向Object的原型。(不包括Object原型对象自身)</p>
<h2 data-tool="mdnice编辑器" style="margin: 20px 10px 0 0; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 22px; text-align: left"><span class="prefix" style="display: none"></span><span class="content" style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">constructor</span><span class="suffix"></span></h2>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">原型中的constructor指向函数本身:</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477598165-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<h1 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 25px; text-align: center; border: 2px dotted rgba(172, 144, 206, 1); border-radius: 6px; background: rgba(222, 198, 251, 1)"><span class="prefix" style="display: none"></span><span class="content" style="display: inline-block; font-weight: bold; color: rgba(89, 89, 89, 1)">思考</span><span class="suffix"></span></h1>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; color: rgba(0, 0, 0, 1); font-size: 16px; font-weight: bold"><span class="prefix" style="display: none"></span><span class="content" style="border-bottom: 3px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">Function原型上都有什么?</span><span class="suffix" style="display: none"></span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">执行下列代码,创建一个普通该函数。</p>
<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px"><code class="hljs" style="overflow-x: auto; padding: 16px; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0; font-size: 12px; -webkit-overflow-scrolling: touch"><span class="hljs-function" style="line-height: 26px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">function</span>&nbsp;<span class="hljs-title" style="color: rgba(153, 0, 0, 1); font-weight: bold; line-height: 26px">a</span>(<span class="hljs-params" style="line-height: 26px"></span>)</span>{}<br></code></pre>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">观察window.a在控制台的打印结果,展开a.__proto__,得到Function.prototype的所有默认属性:</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477611447-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">图中可以看到,a.prototype.__proto__,即Function的原型中:</p>
<ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; font-size: 15px; color: rgba(89, 89, 89, 1); list-style-type: circle">
<li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">有函数方法:call、apply、bind、toString、constructor、Symbol;(标志性就是call、apply、bind这仨)</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">有属性:arguments、caller、以及这俩属性的getter和setter;</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: rgba(89, 89, 89, 1)">最后还有对象:__proto__指向他的构造函数原型(也就是Object.prototype)</section></li></ul>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; color: rgba(0, 0, 0, 1); font-size: 16px; font-weight: bold"><span class="prefix" style="display: none"></span><span class="content" style="border-bottom: 3px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">Object原型上都有什么?</span><span class="suffix" style="display: none"></span></h3>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477619951-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">有函数方法:hasOwnProperty、isPrototypeOf、propertyIsEnumerable、toLocaleString、toString、valueOf、以及constructor<br>
特殊的还有:get __proto__、set __proto__,估计是为了返回null给拦截的。<br>
标志就是get __proto__、set __proto__这俩</p>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; color: rgba(0, 0, 0, 1); font-size: 16px; font-weight: bold"><span class="prefix" style="display: none"></span><span class="content" style="border-bottom: 3px solid rgba(222, 198, 251, 1); color: rgba(89, 89, 89, 1)">其他探索问题</span><span class="suffix" style="display: none"></span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">数组函数的原型上都有什么?<br>
自定义函数的原型上都有什么?</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477628967-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<h1 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 25px; text-align: center; border: 2px dotted rgba(172, 144, 206, 1); border-radius: 6px; background: rgba(222, 198, 251, 1)"><span class="prefix" style="display: none"></span><span class="content" style="display: inline-block; font-weight: bold; color: rgba(89, 89, 89, 1)">练手面试题</span><span class="suffix"></span></h1>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">最后来两道面试题,欢迎评论区一起探讨:</p>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477645527-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477653411-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<figure data-tool="mdnice编辑器" style="margin: 10px 0; display: flex; flex-direction: column; justify-content: center; align-items: center"><img src="https://cdn.jsdelivr.net/gh/xingorg1/xingorg1Blog/2021-8-9/1628477662360-image.png" alt="" style="max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain"></figure>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: rgba(89, 89, 89, 1); margin: 10px 0; letter-spacing: 2px; font-size: 14px; word-spacing: 2px">让我们一起携手同走前端路, 关注公众号【<strong style="color: rgba(255, 0, 0, 1); font-weight: bold">前端印记</strong>】即可。</p>
</section>

</div>
<div id="MySignature" role="contentinfo">
    越努力,越幸运;阿门。<br><br>
来源:https://www.cnblogs.com/padding1015/p/prototype-chain.html
頁: [1]
查看完整版本: 一张图带你搞懂Javascript原型链关系