【JS基礎】原型對象的那些事(二)

上一篇講了javascript

①原型對象是什麼;java

__proto__prototypeconstructor的關係;瀏覽器

③原型對象的做用;函數

④原型對象帶來的一些須要注意的問題;post

沒理解的能夠再複習一下。 傳送門:JS基礎—原型對象的那些事(一)ui

今天講一下原型鏈以及原型鏈的關係圖。this

原型鏈是什麼

每一個對象都有一個__proto__屬性,指向對象的原型。spa

ps:準確的說,是每個實例都有一個[[Prototype]]屬性,指向原型對象。這是一個隱式屬性,存在可是咱們的腳本訪問不到,不過瀏覽器廠商大部分都支持一個__proto__屬性,用來顯示指向原型,雖然能用,但__proto__不是ECMA中的規範。prototype

原型的值能夠是一個對象,也能夠是null。若是它的值是一個對象,那麼這個對象也必定有本身的原型。這樣就造成了一條線性的鏈,咱們稱之爲原型鏈3d

當咱們在對象上調用一個屬性或者方法時,會先在這個對象上尋找,沒有的話就去它的原型對象上找,原型對象上沒有就去原型對象的原型對象上找,一直找到原型對象爲null爲止,沒有的話就是undefined

簡而言之,對象尋找一個屬性會沿着原型鏈向上尋找,直到原型鏈的頂端。

仍是以上一篇的Person爲例

function Person(name) {
    this.name = name
}
Person.prototype.sayName = function() {
    console.log(this.name)
}
var person = new Person("張三")
複製代碼

咱們先來畫一個簡單的關於原型的關係圖

圖片描述

以上是實例構造函數原型對象三者的關係圖。

PS: prototype只是構造函數上的一個屬性,它是一個指針,指向原型對象,並不表示Person.prototype就是原型對象。這裏將Person.prototype認爲是原型對象,是爲了方便理解,須要注意哦。

看不懂的同窗去複習上一篇的內容,看懂的咱們繼續。

注意點一

原型對象也是對象,是對象就有__proto__屬性,指向它的原型對象。

在上一個例子中,Person.prototype就是一個對象,這個對象能夠說是原生Object構造函數的實例,因此

Person.prototype.__proto__ === Object.prototype

Object.prototype也是一個對象,因此它也有__proto__屬性,不過它的__proto__指向null,也就是原型鏈的頂端,再往上就沒有了。

從新補充一下關係圖

圖片描述

看懂的咱們繼續

注意點二

任何函數均可以說是原生Function構造函數的實例。

因此Person構造函數是Function構造函數的實例。

Person.__proto__ === Function.prototype
複製代碼

繼續我完善咱們的關係圖

圖片描述

可能有人疑惑,Person不是函數嗎,函數怎麼也有__proto__,函數不是隻有prototype嗎?

由於函數本質也是對象啊,在JS的世界裏,萬物皆對象,因此函數有__proto__沒毛病。

注意點三

Function.prototype也是對象,因此和Person.prototype同樣,Function.prototype能夠說是原生Object構造函數的實例,因此

Function.prototype.__proto__ === Object.prototype
複製代碼

補充咱們的圖(紅色的線)

圖片描述

注意點四

FunctionObject都是構造函數,根據第二點任何函數均可以說是原生Function構造函數的實例,那麼

Function.__proto__ === Function.prototype
    
    Object.__proto__ === Function.prototype
複製代碼

完善咱們的圖(藍色的線),大功告成。

圖片描述

恩,就是這麼神奇,FunctionFunction的實例。。。

以上就是原型鏈的關係圖,將這個圖弄懂,原型對象的知識基本就掌握了。

雖然在真實場景中,這些知識用到的沒這麼複雜,可是掌握了最基礎的知識,未來出現問題時,就能更快的找到問題的緣由。

對於新手而言,原型鏈和做用域鏈常常搞混,this和靜態做用域不知道在場景中怎麼使用,確實是很頭疼的問題,但這也許就是js的魅力所在吧。

相關文章
相關標籤/搜索