提起原型鏈留量,大家并不陌生,但是對于新人來說一提到原型方面的東西就會比較懵哟冬。在我自一次面試的時候楼熄,面試官也給我提了這樣的問題,當(dāng)時就按照我的理解說了一些柒傻,但是很膚淺孝赫,在此我希望給剛?cè)腴T的前端小伙伴聊一下我理解的原型鏈。
- __ proto__
這個屬性是每個對象都有的屬性红符,指向創(chuàng)建該對象的構(gòu)造函數(shù)原型青柄,其實這個屬性指向了 [[prototype]],但是 [[prototype]] 是內(nèi)部屬性预侯,我們并不能訪問到致开,所以使用 __ proto __ 來訪問。
function add(){}
add.__proto__ === Function.prototype //true
注意:
通過現(xiàn)代瀏覽器的操作屬性的便利性萎馅,可以改變一個對象的 [[Prototype]]
屬性, 這種行為在每一個JavaScript引擎和瀏覽器中都是一個非常慢且影響性能的操作双戳,使用這種方式來改變和繼承屬性是對性能影響非常嚴(yán)重的,并且性能消耗的時間也不是簡單的花費在 obj.__proto__ = ...
語句上, 它還會影響到所有繼承來自該 [[Prototype]]
的對象糜芳,如果你關(guān)心性能飒货,你就不應(yīng)該在一個對象中修改它的 [[Prototype]].。相反, 創(chuàng)建一個新的且可以繼承 [[Prototype]]
的對象峭竣,推薦使用 Object.create()
塘辅。
- prototype 和 constructor
該屬性只有函數(shù)才有,基本所有屬性都有這個屬性皆撩,但是有一個是例外:
Function.prototype.bind()
這個屬性指的是對象的原型扣墩,該屬性有一個屬性constructor,constructor指向構(gòu)造函數(shù)
function add(){}
add.constructor == Function //true
-
new 的時候干了些什么
1.生成一個新對象 {}
2.鏈接到原型
設(shè)置新對象的constructor屬性為構(gòu)造函數(shù)的名稱,設(shè)置proto屬性指 向構(gòu)造函數(shù)的原型對象呻惕,擴(kuò)展了新對象的原型鏈荆责。
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"); // 相當(dāng)于obj.Person("John")綁定this指針
return typeof result === 'object' ? result : obj;
// 如果無返回值或者返回一個非對象值,則將obj返回作為新對象
}
總結(jié)
1.__ proto __所有對象都有亚脆,指向構(gòu)造該對象的原型
2.prototype是對象的原型做院,只有函數(shù)有
3.constrctor是prototype的屬性,指向構(gòu)造函數(shù)