提起原型鏈,你們並不陌生,可是對於新人來講一提到原型方面的東西就會比較懵。在我自一次面試的時候,面試官也給我提了這樣的問題,當時就按照個人理解說了一些,可是很膚淺,在此我但願給剛入門的前端小夥伴聊一下我理解的原型鏈。
*****前端
這個屬性是每一個對象都有的屬性,指向建立該對象的構造函數原型,其實這個屬性指向了 [[prototype]],可是 [[prototype]] 是內部屬性,咱們並不能訪問到,因此使用 __ proto __ 來訪問。面試
function add(){} add.__proto__ === Function.prototype //true
注意:
經過現代瀏覽器的操做屬性的便利性,能夠改變一個對象的 [[Prototype]]
屬性, 這種行爲在每個JavaScript引擎和瀏覽器中都是一個很是慢且影響性能的操做,使用這種方式來改變和繼承屬性是對性能影響很是嚴重的,而且性能消耗的時間也不是簡單的花費在 obj.__proto__ = ...
語句上, 它還會影響到全部繼承來自該 [[Prototype]]
的對象,若是你關心性能,你就不該該在一個對象中修改它的 [[Prototype]].。相反, 建立一個新的且能夠繼承 [[Prototype]]
的對象,推薦使用 Object.create()
。瀏覽器
該屬性只有函數纔有,基本全部屬性都有這個屬性,可是有一個是例外:函數
Function.prototype.bind()
這個屬性指的是對象的原型,該屬性有一個屬性constructor,constructor指向構造函數性能
function add(){} add.constructor == Function //true
***this
new 的時候幹了些什麼prototype
1.生成一個新對象 {}
2.連接到原型
設置新對象的constructor屬性爲構造函數的名稱,設置proto屬性指 向構造函數的原型對象,擴展了新對象的原型鏈。
3.綁定this
4.返回this指針
下面是一個new的過程指針
new Person("John") = { var obj = {}; obj.__proto__ = Person.prototype; // 此時便創建了obj對象的原型鏈: // obj->Person.prototype->Object.prototype->null var result = Person.call(obj,"John"); // 至關於obj.Person("John")綁定this指針 return typeof result === 'object' ? result : obj; // 若是無返回值或者返回一個非對象值,則將obj返回做爲新對象 }
總結
1.__ proto __全部對象都有,指向構造該對象的原型
2.prototype是對象的原型,只有函數有
3.constrctor是prototype的屬性,指向構造函數code