@(JavaScript原型)
JavaScript中最晦澀難懂的恐怕就是原型了。故以此筆記原本記錄原型的學習過程,往後忘了可來溫習。javascript
null
——Object
&Function
——prototype
&constructor
java
__proto__
在JavaScript中,每一個對象都擁有一個原型對象,而指向該原型對象的內部指針則是
__proto__
,經過它能夠從中繼承原型對象的屬性。從對象的__proto__
能夠訪問到它所繼承的原型對象。函數
var a = new Array(); a.__proto__ === Array.prototype //true a.__proto__.__proto__ === Object.prototype //true a.__proto__.__proto__.__proto__ === null //true
如圖,JavaScript中的對象,追根溯源都是來自一個
null
對象。
除了使用.__proto__
方式訪問對象的原型,還能夠經過Object.getPrototypeOf
方法來獲取對象的原型,以及經過Object.setPrototypeOf
方法來重寫對象的原型。post
prototype
函數既是函數又是對象,函數的原型指向
Function.prototype
,函數實例除了有__proto__
屬性以外,還有prototype
屬性。經過該函數構造的新的實例對象,其原型指針__pro__
會指向該函數的prototype
屬性。而函數的prototype
屬性,自己是一個由Object
構造的實例對象。prototype
屬性很特殊,它還有一個隱式的constructor
,指向了構造函數自己。學習
var Foo = function() {}; Foo.__proto__ === Function.prototype //true var a = new Foo(); a.__proto__ === Foo.prototype //true Foo.prototype.__proto__ === Object.prototype //true Foo.prototype.constructor === Foo //true a.constructor === Foo //true a.constructor === Foo.prototype.constructor //true
a.constructor
屬性並不屬於a
而是讀取的a.__proto__.constructor
,因此上圖用虛線表示a.constructor
,方便理解。
即(a.hasOwnProperty("constructor")===false
)prototype
原型鏈做爲實現繼承的主要方法,其基本思想是利用原型讓一個引用類型繼承另外一個引用類型的屬性和方法。
每一個構造函數都有一個原型對象(prototype
),原型對象都包含一個指向構造函數的指針(constructor
),而實例都包含一個指向原型對象的內部指針。
原型鏈的做用在於,當讀取對象的某個屬性時,JavaScript引擎先尋找對象自己的屬性,若是找不到,就到它的原型去找,若是仍是找不到,就到原型的原型去找。以此類推,若是直到最頂層的Object.prototype
仍是找不到,則返回undefined
。指針
instanceof
運算符返回一個布爾值,表示一個對象是否由某個構造函數建立。Object.isPrototypeOf()
只要某個對象處於原型鏈上,isPrototypeOf
都 返回true
var Bar = function() {}; var b = new Bar(); b instanceof Bar //true Bar.prototype.isPrototypeOf(b) //true Object.prototype.isPrototypeOf(Bar) //true
注意:實例
b
的原型是Bar.prototype
而不是Bar
。code
Function.prototype.__proto__ === Object.prototype
Object.prototype.constructor.__proto__ === Function.prototype
即說明Function.prototype
是一個Object
實例,而沒有Function
,Object
也不能建立實例。對象
以下圖:
blog
其中,Op
表明Object.prototype
,Fp
表明Function.prototype
。
以上,參考@Jerrc
---恢復內容結束---
@(JavaScript原型)