一張圖完全理解Javascript原型鏈

代碼

講解用到的代碼很簡單,以下json

function Foo(){
    //屬性和方法
}
var f1 = new Foo();
var f2 = new Foo(); 
var o1 = new Object();
var o2 = new Object();
複製代碼

基礎瞭解

一切皆對象,對象又能夠分爲兩類:瀏覽器

  1. 普通對象 ,除了函數對象以外的對象都是,包括new函數對象()產生的實例,普通對象沒有prototype,也就沒有繼承和原型鏈一說。
  2. 函數對象 ,包括兩種:
  • 由function創造出來的函數:bash

    function f1() {
          } // 匿名函數
          var f2 = function() {
          }
          var f3 = new Function('x','console.log(x)');
          // 以上都是函數對象
    複製代碼
  • 系統內置的函數對象: FunctionObject、Array、String、Number ,Function其實充當了函數對象的構造器,好比Object對象的構造源碼實際上是Function Object() {[native code]}的形式,這一點對於理解原型鏈很重要。函數

進入正題

上圖從結構上分爲實例對象、Functions函數對象、prototype原型對象三部分,圖中f一、f2的原型鏈我特地標成了紅色,Foo的原型鏈爲紫色。

每一個對象都有__proto__屬性,用於儲存繼承得來的方法和屬性;每一個函數對象都有prototype屬性,用於繼承,將其中定義的屬性和方法傳遞給‘後代’(好比實例化)。post

如何實現原型繼承

f1爲什麼有Foo、Object的原型方法,其實就是經過原型鏈繼承。繼承的過程能夠表示爲f1.__proto__ = Foo.prototype,即對象.__proto__ = 構造器.prototype學習

new實例實現繼承的過程其實與上面原理相同,new的過程能夠拆解爲下面幾個步驟:ui

var temp = {};
temp.__proto__ = Foo.prototype; // 原型繼承
var f1 = Foo.call(temp);
return f1;
複製代碼

找出原型鏈

1) f1的原型鏈(紅色虛線)。

  1. f1爲普通對象,它的構造器爲Foo,以Foo爲原型,原型鏈第一鏈爲f1.__proto__ == Foo.prototype
  2. Foo.prototype(注意這邊不是Foo)爲json對象,即普通對象,構造器爲Object,以Object爲原型,得出原型鏈第二鏈Foo.prototype.__proto__ == Object.prototype;
  3. Object.prototype以Null爲原型,原型鏈第三鏈爲Object.prototype.__proto__ == null

 f1的原型鏈能夠用圖形表示:spa

 能夠在瀏覽器console打印驗證:prototype

2) Foo的原型鏈(紫色虛線)

  1. Foo爲函數對象,它的構造器爲Function,以Function爲原型,原型鏈第一鏈爲Foo.__proto__ == Function.prototype;
  2. Function.prototype爲json對象,即普通對象,構造器爲Object,以Object爲原型,原型鏈第二鏈爲Function.prototype.__proto__ == Object.prototype;
  3. 最後Object.prototype以Null爲原型,原型鏈第三鏈爲Object.prototype.__proto__ == null;

 Foo的原型鏈能夠用圖形表示爲:3d

 能夠在瀏覽器console打印驗證:

3)小結

列出兩種原型鏈的目的是:

當js引擎執行對象的屬性或方法時,先查找對象自己是否存在該方法,若是不存在則會在原型鏈上查找。

於是f1擁有Foo、Object的原型方法,Foo擁有Function、Object的原型方法。

注意,雖然f1原型鏈其中有一鏈是涉及到函數對象Foo,但f1並不擁有Function的原型方法,由於原型鏈並無延伸到Function。

好比下圖中bind是Function的原型方法,f1並無擁有。

總結

如何找出一個對象的原型鏈,只須要兩步

  1. 判斷對象是普通對象仍是函數對象,得出對象的構造器
  2. 對象.proto = 構造器.prototype

關於最上面的圖形,只剩Object和Function的特殊關係和構造函數constructor沒有講到, 瞭解Object和Function的關係,戳這兒~

若是有講不清和講錯了的地方,請幫我指出來,我也跟你們一塊兒在學習中,請輕噴(●ˇ∀ˇ●)

相關文章
相關標籤/搜索