對`prototype`和`__proto__`的理解
談談對prototype
和__proto__
的理解
之前初學JavaScript的時候,被這兩個東西搞得迷迷糊糊的,前兩天看JS高程的時候,看到了prototype,自己好好的總結了一下
1. 建構函式,原型物件,例項
建構函式的原型屬性 prototype
指向了原型物件,在原型物件有的屬性和方法,建構函式構造出的例項都可以繼承共享,不是很恰當的說,如果建構函式是例項的爹,那麼原型物件就是建構函式的爹,也就是例項爹的爹,爺爺。
建構函式是函式
原型物件的物件
例項也是是物件
以下列程式碼為例:
function Foo () {}
foo = new Foo ()
上面程式碼創造了一個建構函式,並new了一個Foo的例項foo,我們可以在控制檯列印下面程式碼
可以很明顯看到,Foo建構函式是一個function,而foo例項和Foo.prototype原型物件都是物件
2. 關係示意圖
3. 詳解
prototype 是屬於一個函式特有的屬性,而
__proto__
一般存在於物件之中
-
Foo函式作為一個建構函式,它的的prototype指向它的原型,Foo.prototype是一個物件,裡面的屬性和方法能傳給Foo構造的例項之中。
-
而Foo.prototype這的物件有一個屬性 為
constructor
(構造器屬性),constructor屬性指向原型物件對應的建構函式,也就是指向 Foofoo.constructor --> ƒ Foo() {}
-
物件具有
__proto__
可稱為隱式原型,一個物件的隱式原型,指向構造改物件(foo)的建構函式(Foo)的原型(Foo.prototype),這也保證了例項能夠訪問繼承建構函式原型物件中的屬性和方法所以,
foo.__porto__ === Foo.prototype
-
物件沒有prototype屬性,所以
foo.prototype = undefined
-
但是函式可以有
__proto__
屬性,因為函式的本質也是一個物件Foo是一個方法,既一個函式,函式本身也是一個特殊的物件,把Foo作為一個物件來看,它的
__proto__
指向Foo建構函式本身的建構函式的原型,Foo建構函式的建構函式是是Function
Foo.constructor --> ƒ Function() { [native code] }
(後者即是Function)Foo.constructor === Function
// trueFoo.constructor.prototype === Foo.__proto__
// trueFunction.prototype === Foo.__proto__
// true -
原型物件是物件,也有
__proto__
屬性,我們可以在控制檯列印Foo.prototype.__proto__
發現出現了一個物件,裡面有很多屬性 包括 constructor, hasOwnProperty, isPrototypeOf,等等的方法其實這個物件就是Object.prototype, 而Object就是這個原型物件的建構函式
這裡的Object是一個建構函式,不是一個物件,不要搞錯,typeof(Object) --> function
-
最後我們看一下Object.prototype這個物件的
__proto__
屬性,我們會發現為NullObject.prototype.__proto__
// null -
Function.prototype === Function.__proto__
// trueFunction的原型和Function的
__proto__
竟然全等,構造Function的建構函式的原型 等於 Function的原型我們發現一個有趣的東西
Function
是由Function
構造的 ,Function可以看成是呼叫其自身的new操作的例項化的結果,哈哈 有點意思,沒爹,自己把自己搞出來了。。我們接著試探,發現
Function.prototype
當做一個物件來看,他的建構函式是Object( )函式,那麼Function.prototype.__proto
也就是Object的原型了所以
Function.prototype.__proto__ ===Object.prototype
// true
4. 總結
- 物件有屬性__proto__,指向該物件的建構函式的原型物件
- 方法除了有屬性__proto__,還有屬性prototype,prototype指向該方法的原型物件
- 函式(Function也是函式)是new Function的結果,所以函式可以作為例項物件,其建構函式是Function(),原型物件是Function.prototype
- 物件(函式也是物件)是new Object的結果,所以物件可以作為例項物件,其建構函式是Object(),原型物件是Object.prototype
- Object.prototype的原型物件是null