JavaScript中的繼承是靠什么?什么是構造函數(shù)?什么是原型鏈?這一切到底是什么?

首先理解一下構造函數(shù)
JavaScript的構造函數(shù)并不是作為類的一個特定方法存在的;當任意一個普通函數(shù)用于創(chuàng)建一類對象時,它就被稱作構造函數(shù),或構造器。一個函數(shù)要作為一個真正意義上的構造函數(shù),需要滿足下列條件:
1、 在函數(shù)內(nèi)部對新對象(this)的屬性進行設置,通常是添加屬性和方法。
2、 構造函數(shù)可以包含返回語句(不推薦),但返回值必須是this,或者其它非對象類型的值。
再看自定義函數(shù)與Function之間到底存在著什么關系?它兩有什么區(qū)別?
其實自定義函數(shù)全是Function的實例
最后看看Obeject與Function是啥子東西?
ECMAScript規(guī)定了兩個特殊的內(nèi)置對象:Object和Function。他們的特殊性在于,他們本身既是對象又是函數(shù),而他們同時也是對象和函數(shù)的構造器。是不是很饒人。想想就頭大...??
- Object
Object對象本身是一個函數(shù)對象。既然是Object函數(shù),就肯定會有prototype屬性,所以可以看到”O(jiān)bject.prototype”的值就是”O(jiān)bject {}”這個原型對象。反過來,當訪問”O(jiān)bject.prototype”對象的”constructor”這個屬性的時候,就得到了Obejct函數(shù)。 - Function
JavaScript中函數(shù)也是對象,所以就可以通過proto查找到構造函數(shù)對象的原型。
Function對象作為一個函數(shù),就會有prototype屬性,該屬性將對應”function () {}”對象。
Function對象作為一個對象,就有proto屬性,該屬性對應”Function.prototype”,也就是說,”Function.proto === Function.prototype”。
我們開始說事情吧!
_proto_和prototype
_proto_
_proto_屬性存在每個對象中,用來指向創(chuàng)建它的對象的prototype。打個比方假如你是一個對象誰生了你你得_proto_就指向誰的prototype。
prototype
prototype屬性存在每個函數(shù)對象中,當一個函數(shù)被用作構造函數(shù)來創(chuàng)建實例的時候,該函數(shù)的prototype屬性將被作為原型賦值給所有創(chuàng)建的實例(也就時候?qū)嵗械腳proto_)
const Demo = function () {
this.name = 'demo'
this.sayName = function () {
console.log(this.name)
}
}
const instanceA = new Demo()
const instanceB = new Demo()
console.log(instanceA.__proto__ === Demo.prototype)
console.log(instanceB.__proto__ === Demo.prototype)
// true
// true
原型鏈
每個對象都有原型,一個實例的_proto_指向創(chuàng)建它的構造函數(shù)對象的prototpe,而構造函數(shù)對象的_proto_又指向父級構造函數(shù)原對象的prototype,這樣層層的連接就形成了原型鏈。如下圖所示藍色所形成的就稱為原型鏈。

每個對象都有constructor指向父級對象所以全部關系圖如下。

原型繼承
看下面例子
const Demo = function () {
this.name = 'demo'
this.sayName = function () {
console.log(this.name)
}
}
const instanceA = new Demo()
console.log(instanceA,name) // demo
instanceB.sayName() // demo
instanceA通過原型鏈訪問到了Demo的屬性與方法。換一種說法就是instanceA繼承了Demo的屬性與方法。
const instanceA = new Demo()
instanceA.name = 'instanceA'
instanceA.sayName() // instanceA
在我們?yōu)閕nstanceA添加一個name屬性的時候輸出的卻是后面添加的屬性值。這就牽扯到了屬性優(yōu)先級(這里這樣稱呼)
優(yōu)先級原則:函數(shù)對象本身的屬性或方法的優(yōu)先級要高于原型的屬性或方法
總結:
1.原型和原型鏈是Js實現(xiàn)繼承的一種模型。
2.原型鏈的形成真正靠的是proto而非prototype.