我知道的JS原型的那些事

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


waht.jpg

首先理解一下構造函數(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ù)的構造器。是不是很饒人。想想就頭大...??

  1. Object
    Object對象本身是一個函數(shù)對象。既然是Object函數(shù),就肯定會有prototype屬性,所以可以看到”O(jiān)bject.prototype”的值就是”O(jiān)bject {}”這個原型對象。反過來,當訪問”O(jiān)bject.prototype”對象的”constructor”這個屬性的時候,就得到了Obejct函數(shù)。
  2. 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,這樣層層的連接就形成了原型鏈。如下圖所示藍色所形成的就稱為原型鏈。

prototype.jpg

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

all_prototype.jpg

原型繼承

看下面例子

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.

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容