function Animal() { } var cat = new Animal(); cat.name = 'Tom'; console.log(cat.name) // Tom
每一個函數都有一個 prototype 屬性
函數的 prototype 屬性指向了一個對象,這個對象正是調用該構造函數而建立的實例的原型,也就是這個例子中的 cat
和 dog
的原型。javascript
function Animal() { } // 雖然寫在註釋裏,可是須要注意:prototype是函數纔會有的屬性 Animal.prototype.name = 'Tom'; var cat = new Animal(); var dog = new Animal(); console.log(cat.name) // Tom console.log(dog.name) // Tom
每個JavaScript對象(null除外)在建立的時候就會與之關聯另外一個對象,這個對象就是咱們所說的原型,每個對象
都會從原型"繼承"屬性。java
如何表示實例與實例原型之間的關係呢,這裏須要提到 proto
每個JavaScript對象(除了 null )都具備的一個屬性,叫__proto__,這個屬性會指向該對象的原型數組
每個對象數據類型的值,都自帶__proto__屬性,這個屬性用來指向所屬類的原型prototype函數
function Animal() { } var cat = new Animal(); console.log(cat.__proto__ === Animal.prototype); // true
實例對象和構造函數均可以指向原型學習
每一個原型都有一個 constructor
屬性指向關聯的構造函數spa
function Animal() { } console.log(Animal === Animal.prototype.constructor); // true
則能夠得出prototype
function Animal() { } var cat = new Animal(); console.log(cat.__proto__ == Animal.prototype) // true console.log(Animal.prototype.constructor == Animal) // true // 順便學習一個ES5的方法,能夠得到對象的原型 console.log(Object.getPrototypeOf(cat) === Animal.prototype) // true
當讀取實例的屬性時,若是找不到,就會查找與對象關聯的原型中的屬性,若是還查不到,就去找原型的原型,一直找到最頂層爲止。code
function Animal() { } Animal.prototype.name = 'Tom'; var cat = new Animal(); cat.name = 'Jerry'; console.log(cat.name) // Jerry delete cat.name; console.log(cat.name) // Tom
咱們給實例添加了name屬性,放咱們打印cat.name
時結果天然是Jerry。當咱們刪除了cat的name屬性時,讀取cat.name時,從對象中沒法找到name屬性,就會從cat的原型,也就是cat.__proto__
,同時也是Animal.prototype
中查找,找到結果爲Tom。對象
反問:倘若沒有找到該怎麼辦呢?原型的原型又是誰呢?blog
原型對象其實就是經過Object
構造函數生成的,實例的__proto__
指向構造函數的prototype
提問:Object.prototype
的原型呢?
是null,能夠打印一下看看:
console.log(Object.prototype.__proto__ === null) // true
null 表示「沒有對象」,即該處不該該有值。
Object.prototype.__proto__
的值爲null跟Object.prototype
沒有原型,實際上是一個意思。
查找屬性的時候查到Object.prototype就中止查找了。
圖中黃色的線就是相互關聯的原型組成的鏈狀結構
——原型鏈。
因爲函數也是對象,會在內存中單獨開闢一個空間,所以,當實例對象多的時候,就會出現內存空間被不少重複的函數佔用。
如:有100個 Person 的實例對象,那麼在內存空間裏就會有100個eat方法佔用的空間,這些方法分別指向不一樣的實例對象。可是他們的執行結果卻都是同樣的。這就形成了內存空間的浪費!
爲解決這個問題,咱們須要一個共享的空間,在裏面存放一些公共的方法,屬性,這就是原型。
JavaScript原型就是爲了實現對象之間的聯繫,解決構造函數沒法數據共享而引入的一個屬性。原型鏈就是一個實現對象間聯繫即繼承的主要方法。