完全深入理解js原型鏈之prototype,__proto__以及constructor(二)

前言

若是你可以啃下教程一而且吃透原型鏈的幾個概念的話說明你在前端飛仙的路上又進了一小步···學習最怕的不是慢而是站!這篇教程主要目的對原型鏈概念進一步加深理解html

鞏固下教程一的知識

來看下面的例子:前端

var text=new String("我是文字");
function Persion(name,job){
    this.name=name;
    this.job=job;
}
Persion.myName="lxm";
Persion.prototype.sayName=function(){
    alert(this.name);
}
var perison1=new Persion("lxm","20")
思考:判斷下列表達式返回的值:

(兩分鐘以內對八道的算及格,剩下的同窗回頭接着理解教程一,傳送門在此 [http://0313.name/2017/01/13/p...])git

perison1.__proto__===Persion.prototype;
perison1.name===Persion.name;
perison1.prototype.__proto__===Object.prototype;
Persion.prototype.__proto__===Object.prototype;
Persion.__proto__===Function.prototype;
Persion.constructor===perison1;
Function.__proto__===Object.prototype;
Function.prototype.__proto__===Object.prototype;
typeof Persion.prototype;
typeof Function.prototype;

原型鏈圖

這個圖絕對是網絡上獨一無二獨一份,此乃小米飛昇教程獨家祕籍!由於博主在學習過程當中發現對文字的理解和記憶遠遠不如一個圖來的更深更直觀,更加透徹,爲了您更好的學習原型鏈,博主特地花了一上午的時間用mermaid繪製了這個原型鏈的關係圖,並且經過這個圖咱們可以發現不少有意思的事情
爲了關係圖更加直觀和清晰,隱去了一些引用線路,其中:網絡

  • 圓形表明對象的名字
  • 方形表明屬性名
  • 實線表明對象的分界
  • 虛線表明引用
  • 菱形表明基本值

git

  1. 原型鏈是單鏈,只往一個方向流向,沒有迴路
  2. 只有Function的__proto__指向本身的prototype,這也向咱們解釋了爲何Function.prototype類型是function
  3. 咱們經過__proto__只能獲取到原型對象中的方法和屬性,因此persion1經過原型鏈是獲取不到Persion的myName屬性,可是咱們能夠經過原型對象的constructor來獲取或者修改Persion的屬性(這點太給力了)
請注意,有時候這個方法也很差使,由於原型對象的constructor是能夠改變的,不必定指向原型對象所在的函數對象

繼續上面的例子:函數

persion1.__proto__.constructor.myName="我變了耶!";
console.log(Persion.myName); //我變了耶
  1. 普通對象的_proto__必定指向創造它的函數對象的prototype
  2. 原型對象的__proto__必定指向Object.prototype!
  3. 經過圖咱們能夠簡單理解,擁有原型對象屬性的對象是函數對象,不然爲普通對象
  4. 原型鏈是有開始和盡頭的,開始於null,結束於普通對象
  5. 全部的函數對象都是Function以new的方式創造出來了,包括Function本身且每一個函數對象的__proto__都指向了Function.prototype
  6. Object是全部對象的父類,咱們也能夠稱之爲基類,不過不要糾結於叫什麼,由於咱們經過圖能夠看到每個對象(不論是原型對象仍是普通對象仍是函數對象)的經過原型鏈均可以引向Object.prototype

以上九條我稱爲原型鏈之九句真言(不要太在乎名字,我本身隨便起的 ~) 學習

意外收穫:this.name和this.job難道不該該在Persion中也有一份嗎?無數個日夜,愚笨的博主對this的用法都不甚瞭解,直到我畫出了這種圖,我tm完全明白了this的含義,就是誰運行包含this的這個函數,this就把掛在它身上的包袱(屬性)甩給誰!
看到了嗎,persion1調用了Persion,那麼天然多了2個屬性,可是注意,name跟job並非Persion的屬性!!

思考:圖中沒有畫出Object.__proto__的指向,請問他指向哪?(請只依據九句真言解答)this

思考題解答

思考:判斷下列表達式返回的值:

perison1.__proto__===Persion.prototype;
首先判斷perison1是經過new方式被Persion創造出來的,依據九句真言第4條得出 :true
perison1.name===Persion.name;
經過關係圖能夠看到不相等,我已經在乎外收穫中解答了,答案爲:false
perison1.prototype.__proto__===Object.prototype;
只看圖能夠看到perison1沒有prototype,是普通對象因此答案爲:js報錯~~
Persion.prototype.__proto__===Object.prototype;
參考九句真言第5條:答案爲:true
Persion.__proto__===Function.prototype;
Persion爲函數對象,參考九句真言第8條,答案爲:true
Persion.constructor===perison1;
Persion是由Function創造出來的因此Persion.constructor指向Function,答案爲:false
Function.__proto__===Object.prototype;
Function咱們已經反覆強調是由自身創造因此Function.__proto__===Function.prototype;,答案爲:false
Function.prototype.__proto__===Object.prototype;
根據九句真言第5條,答案爲:true
typeof Persion.prototype;

答案爲:objectspa

typeof Function.prototype;

答案爲:function,注意這個是比較特殊的原型對象prototype

思考:圖中沒有畫出Object.__proto__的指向,請問他指向哪?(請只依據九句真言解答)

下面來分步解答code

  1. Object屬於函數對象
  2. 依據九句真言第八條得出函數對象的__proto__都指向了Function.prototype
  3. 因此Object.__proto__===Function.prototype

這一點是不太好理解的,是Function創造了Object,而後Object創造了Function的原型對象prototype
因此就有了

Object.__proto__===Function.prototype
Function.prototype.__proto__===Object.prototype

不要太糾結於此,只要理解就好

結束語

好了,原型鏈的概念原理經過這2篇教程我相信你們已經倒背如流了!下面的教程,咱們會着重研究下原型鏈在實際的應用!

做者 宜信技術學院 劉曉敏
相關文章
相關標籤/搜索