徹底搞懂Object和Function的關係

陳贇發表於2018-07-09

Object和Function的關係其實屬於原型鏈的知識範疇,如果對於原型鏈、原型繼承還不熟悉的話,可以戳這邊o( ̄▽ ̄)o

Object、Function和其它物件的關係可以歸納為下面四點:

  1. 一切物件都最終繼承自Object物件,Object物件直接繼承自根源物件null
  2. 一切函式物件(包括Object物件)都直接繼承自Function物件
  3. Object物件直接繼承自Function物件
  4. Function物件直接繼承自己,最終繼承自Object物件

是不是感覺有點繞,下面我會逐點解釋(下面的"一切物件"指除null的其它一切物件):

1. 一切物件都最終繼承自Object物件,Object物件直接繼承自根源物件null

下面兩點可以佐證:

1)一切物件的原型鏈最終都是.... → Object.prototype → null。例如定義一個num變數var num = 1,則num的原型鏈為x → Number.prototype → Object.prototype → null; 定義一個函式物件fnfunction fn() {},則fn的原型鏈為fn → Function.prototype → Object.prototype → null;等等...

2)一切物件都包含有Object的原型方法,Object的原型方法包括了toString、valueOf、hasOwnProperty等等,在js中不管是普通物件,還是函式物件都擁有這些方法,下面列出了幾個例子,大家可以自行去舉例驗證:

徹底搞懂Object和Function的關係

2. 一切函式物件(包括Object物件)都直接繼承自Function物件

函式物件包括了Function、Object、Array、String、Number,還有正則物件RegExp、Date物件等等,它們在js中的構造原始碼都是function xxx() {[native code]);,Function其實不僅讓我們用於建構函式,它也充當了函式物件的構造器,甚至它也是自己的構造器。

從原型鏈可以佐證:

徹底搞懂Object和Function的關係
js中物件.__proto__ === 構造器.prototype,由此可以見得它們之間的關係。

疑:Object物件都繼承自Function物件了,而一切物件又都繼承自Object物件,這邊是不是有矛盾,Object物件和Function物件的關係是不是有點♂復♀雜?

答:其實疑問的內容就是上面結論的三四點,它們沒有矛盾,關係也不復雜。

  1. 一切物件都繼承自Object物件是因為一切物件的原型鏈最終都是.... → Object.prototype → null,包括Function物件,只是Function的原型鏈稍微繞了一點,Function的原型鏈為Function → Function.prototype → Object.prototype → null,它與其它物件的特別之處就在於它的構造器為自己,即直接繼承了自己,最終繼承於Object,上面的原型鏈可以在瀏覽器驗證:

徹底搞懂Object和Function的關係
2. Object繼承自Function,Object的原型鏈為Object → Function.prototype → Object.prototype → null,原型鏈又繞回來了,並且跟第一點沒有衝突。可以說Object和Function是互相繼承的關係。

3、4點的解答在第2點中

疑問

1)一切物件繼承自Object,Object又繼承自Function,那一切物件是不是都有Function的原型方法?

答:不對,普通物件都沒有Function的原型方法。從我們所寫原型鏈中可以看出,Object是繼承自Function,而Object也有Function的原型方法(比如bind),但Object繼承得到的方法儲存於__proto__屬性中,普通物件從Object繼承到的原型方法卻在於prototype屬性中,因而不對。

2)Function物件怎麼那麼怪,自己繼承自己?

答:就是 就是。

總結

Object物件直接繼承自Function物件,一切物件(包括Function物件)直接繼承或最終繼承自Object物件。

(有說得不夠清楚或者錯誤的地方,歡迎拍磚~)

相關文章