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