函數原型鏈
任意的一個函數,都是相當於Function
的實例。類似於{}
與new Object()
的關係。
-
函數應該有什麼屬性?
__proto__
- 把函數當做構造函數來看,關注其
prototype
屬性 - 把函數當做對象來看,關注其__proto__屬性
- 這兩個屬性的切入點是不一樣的
- 把函數當做構造函數來看,關注其
- 函數的構造函數是什麼?
Function
- 函數應該繼承自
Function.prototype
-
Function.prototype
繼承自Object.prototype
繪製函數的構造原型實例結構
- 原型也是對象,所以原型對象中也存在
__proto__
屬性,原型對象的__proto__
屬性指向Object
原型對象 -
Object.prototype
的原型是null
-
Object
構造函數是函數,一切函數在Function
構造函數面前都是對象-
Object
構造函數是Function
構造函數的實例對象 -
Object
作爲對象是繼承自Funtion.prototype
的,又Function.prototype
繼承自Object.prototype
-
繪製Function的構造原型實例的三角形結構
Function是構造函數,所有的函數是Function構造函數的實例,構造函數也是函數,所以所有的構造函數也是Function構造函數的實例,所以Function即是構造函數,也是實例,所以Function是自己的構造函數,是它自己創造了自己
由於Function
是自己的構造函數也是自己的實例,所以Function
構造函數中既有prototype
屬性也有__proto__
屬性。
繪製Function與Object的關係
-
Function
構造函數的prototype
屬性指向Function.prototype
原型對象,Function.prototype
原型對象的原型是Object
原型對象 -
Object
構造函數的構造函數是Function
構造函數,也就是Function
構造函數實例化了Object
構造函數,所以Object
構造函數作爲對象來說,它本身也有__proto__
屬性,指向了Function.prototype
原型對象(曲線) - 在JavaScript中,最牛的
Function
構造函數(函數的老大)的原型對象都要繼承自Object
原型對象;最牛的Object
構造函數(對象的老大)都是由Function
構造函數創建出來的
結論
- 在JavaScript中任何對象的老祖宗就是
Object.prototype
- 在JavaScript中任何函數的老祖宗就是
Function.prototype
- 由於
Function.prototype
繼承自Object.prototype
,所以任何函數的老祖宗也是Object.prototype
(此條結論是推導出來的,主要記上面兩條結論)
規則雜談
- 如果在代碼中希望給所有的對象都提供一個方法,那麼就給
Object.prototype
對象添加一個方法 - 如果希望給所有的函數都提供一個方法,那麼就給
Function.prototype
對象添加一個方法