Javascript之傻傻理不清的原型鏈、prototype、__proto__

Javascript之傻傻理不清的原型鏈、prototype、__proto__

 

新人學習Javascript,其中的原型鏈一直是雲裏霧裏,不得要領,查了不少相關資料,以爲這遍講得最爲清晰易懂,特轉載分享,共同窗習。javascript

1. JavaScript內置對象

所謂的內置對象 指的是:JavaScript自己就本身有的對象 能夠直接拿來就用。例如Array String 等等。JavaScript一共有12內置對象java

其中10個函數類型( String,Number,Boolean,Array,Function,Date,RegExp,Error,Object,Event )函數類型 有 __proto__和 prototype 屬性瀏覽器

2個對象類型(Math,JSON) 對象類型只有__proto__屬性。app

下面有一張圖片 由蘇仔提供。函數

Javascript之傻傻理不清的原型鏈、prototype、__proto__

 

2. 感性認識JS裏的「德羅斯特效應」之原型鏈

打開瀏覽器的控制面板,隨便輸入一個JS內置的構造器函數,好比Array,控制檯輸出的是一個名爲Array的函數體,這好像並無什麼稀奇的,可是,當你接着輸入Array.prototype,控制面板輸出了一堆咱們常常用到的Array構造器的方法,把目光轉移到最下方,有一個叫__proto__的屬性,好奇的點開。列表列出的不是Object構造器的方法麼,裏邊有咱們很是熟悉的hasOwnProperty還有toString等方法。若是Array是構造器,那麼控制面板輸出的Array.prototype的全部屬性中constructor又是什麼構造器?點開看看,以後就像身處德羅斯特效應中同樣,__proto__和constructor,還有Array構造器中經常使用的方法名不斷的出現,一層套一層,一層層展開,沒有盡頭。。。學習

怎麼證實 你是你?測試

拿Array舉例,Array.prototype中有一個constructor屬性,這個屬性的值就是Array構造器本身。 因此我在console裏面測試prototype

(每個構造函數都有)設計

Javascript之傻傻理不清的原型鏈、prototype、__proto__

 

二、「遺傳進化鏈__proto__」,怎麼證實一切皆對象?3d

全部的JS內置構造器都本是對象。但是從什麼線索開始向過去前進呢,原型鏈(我給他起了一個名字叫遺傳進化鏈)就是突破口。全部JS構造器(固然不止構造器有)都有一個__proto__屬性,這是原型鏈指針,指向遺傳進化成它的「那個」。它「遺傳」了「那個」的特性,而又進化出了它自有的特性。

Javascript之傻傻理不清的原型鏈、prototype、__proto__

 

這裏Array 是內置對象且是函數類型。因此Array有__proto__屬性 指向的是函數類型 (function(){})。因此當咱們在輸出Array.__proto__.proto__;就會返回對象類型(Object{}).可是再向上就null。由於Object就是父類了。全部的繼承自Object。

JS內置構造器其中之一的Array本來就是一個函數,而這個函數就是Function的prototype,因此Function.prototype有的方法,JS內置構造器都有,好比call()、apply()、bind()等(其實咱們自定義的函數也是繼承自Function.prototype,因此咱們本身也能夠定義構造器)。而Function.prototype的進化鏈指針又指向了Object.prototype。

三、怎麼證實到頭來一切都是空?

Javascript之傻傻理不清的原型鏈、prototype、__proto__

 

四、怎麼證實全部JS內置構造器和自定義函數都是Function構造器的原型(prototype)。

10個函數類型構造器的進化鏈指針__proto__指向Function構造器的原型.

Javascript之傻傻理不清的原型鏈、prototype、__proto__

 

這裏須要注意全部構造器的prototype都是對象(object)類型,只有Function.prototype是函數(function)類型,這是爲了保證函數構造器們的__proto__指向的都是函數。

3. JSON和Math

JS內置的構造器函數均可以使用new關鍵字實例化一個對象,咱們稱實例化後的這個對象就是某某構造器的一個實例。就像咱們每個「人」都是「人類」這個構造器函數的一個實例。

 

Javascript之傻傻理不清的原型鏈、prototype、__proto__

 

咱們試試JSON 和Math 能不能實例化對象。

 

Javascript之傻傻理不清的原型鏈、prototype、__proto__

 

不能夠。JSON和Math不是構造器函數,他們是普通的對象。

只有構造器函數才能使用new 關鍵字實例化一個對象,而JSON和Math已是對象了,因此咱們能夠不用實例化直接使用JSON和Math中的屬性和方法~~(咱們實例化的目就是想用實例化後的對象裏的屬性和方法,那麼既然JSON和Math已是對象了,就省去實例化的操做 直接使用靜態方法。

因此JSON和Math不屬於10個構造器函數,但他們12個共同屬於Javascript的內置對象。

4. __proto__進化鏈指針設計爲何如此重要

javascript中爲何會有__proto__原型鏈的設計。

先實例化一個String對象並將其賦值給str這個變量,而後咱們輸出這個str

Javascript之傻傻理不清的原型鏈、prototype、__proto__

 

從str輸出的內容來看,str有四個屬性,分別是0、一、二、length。

可是 str.charAt(0); // l

str裏面沒有charAt()方法 可是沒有報錯。這是由於str的進化鏈上存在這個屬性方法,那麼charAt()這個方法在進化鏈的那個節點上呢。

Javascript之傻傻理不清的原型鏈、prototype、__proto__

 

原來String.prototype擁有charAt這個方法,而str的__proto__指針指向String.prototype。str.__proto__.__proto__指向的對象所擁有的屬性str也均可以直接用

看到str.__proto__.__proto__指向的對象所擁有的屬性中有一個hasOwnProperty屬性方法了麼,str能夠直接使用這個屬性方法 在驗證以前先說下str.__proto__.__proto__指向了誰?指向的是Object的prototype屬性。

Javascript之傻傻理不清的原型鏈、prototype、__proto__

 

Object.prototype.hasOwnProperty()屬性方法用來檢驗一個對象是否本身擁有一個屬性而非經過進化鏈__proto__繼承來的屬性。

Javascript之傻傻理不清的原型鏈、prototype、__proto__
相關文章
相關標籤/搜索