原型(prototype)
在 JavaScript 中,每當(dāng)定義一個對象(函數(shù)也是對象)時候,對象中都會包含一些預(yù)定義的屬性。其中每個函數(shù)對象都有一個prototype 屬性,這個屬性指向函數(shù)的原型對象。
每個對象都有__proto__ 屬性,但只有函數(shù)對象才有 prototype 屬性。
原型的作用
通過構(gòu)造函數(shù)為實例對象定義屬性有一個缺點,同一個構(gòu)造函數(shù)的多個實例之間,無法共享屬性,從而造成對系統(tǒng)資源的浪費。
JavaScript 繼承機(jī)制的設(shè)計思想就是,原型對象的所有屬性和方法,都能被實例對象共享。也就是說,如果屬性和方法定義在原型上,那么所有實例對象就能共享,不僅節(jié)省了內(nèi)存,還體現(xiàn)了實例對象之間的聯(lián)系。
__proto__
JS 在創(chuàng)建對象(不論是普通對象還是函數(shù)對象)的時候,都有一個叫做__proto__ 的內(nèi)置屬性,用于指向創(chuàng)建它的構(gòu)造函數(shù)的原型對象。
Number、String、Boolean類型有各自的共有屬性__proto__,各自的共有屬性__proto__又指向了普通對象Object的__proto__,普通對象Object的__proto__指向null
var o1 = {}
o1.__proto__ === Object.prototype //true
var n1 = new Number(1)
n1.__proto__ === Number.prototype //true
n1.__proto__.__proto__ === Object.prototype //true
n1.__proto__.__proto__.__proto__ === null //true
原型鏈
原型鏈的基本思想就是利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。
JavaScript引擎在訪問對象的屬性時,如果在對象本身中沒有找到,則會去原型鏈中查找,如果找到,直接返回值,如果整個鏈都遍歷且沒有找到屬性,則返回undefined。