成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一文讀懂JavaScript原型鏈

開發 前端
對象通過隱式原型( __proto__? )屬性指向其構造函數的原型對象( prototype? ),進而通過原型對象( prototype? )的隱式原型( __proto__? )屬性指向更高層級的原型對象( prototype? ),最終指向null而停止所形成的鏈條,則稱其為原型鏈。

前言

什么是原型鏈

每個對象(Object)都有一個私有屬性指向另一個名為原型(prototype)的對象。原型對象也有一個自己的原型,層層向上直到一個對象的原型為 null。根據定義,null 沒有原型,并作為這個原型鏈(prototype chain)中的最后一個環節。

說明

  1. __proto__實際為[[Prototype]]屬性的訪問器,為了便于理解,本文以屬性代稱其訪問器實質
  2. 這里不使用class表達式是因為class表達式實際上是特殊的函數,更類似于將多個操作融合后的語法糖。使用Function來理解更為直觀
  3. 所有代碼均已在Chrome瀏覽器v125.0.6422.142經過結果驗證

一、名詞解釋

在開始了解原型鏈之前,先介紹兩個名詞prototype以及__proto__,舉一個簡單的例子更為直觀

定義一個函數Foo,而后創建一個Foo的實例對象o1。

function Foo(){}
const o1 = new Foo()

(一)、原型對象(prototype)

[!NOTE]

所有的函數都是對象,擁有獨有屬性prototype

prototype原型對象,是函數的獨有屬性。該屬性指向一個對象。當函數(如:Foo)被實例化成一個對象(如:o1)后,實例對象(o1)可以訪問到函數(Foo)的原型對象(prototype)

如:在Foo的prototype上增加屬性propA,其值為'p1',可以發現在o1上也可以獲取到屬性propA,其值同樣為'p1'

Foo.prototype.propA = 'p1'
o1.propA // 'p1'

那么o1是如何獲取到Foo.prototype上的方法的呢,這就要介紹另一個概念,隱式原型__proto__

(二)、隱式原型(__proto__)

[!Note]

所有非內置對象都是函數的實例,擁有獨有屬性__proto__

__proto__隱式原型,是對象的獨有屬性。對象(如:o1)的__proto__屬性指向其構造函數(如:Foo)的原型對象( prototype )。所有非內置對象都是函數的實例,同時擁有一個構造函數。如:對象o1的構造函數為Foo

內置對象如:Function、Date、Array、Object、Math、JSON等。

如:o1上訪問到的屬性propA實際上是其構造函數Foo的prototype的屬性propA。這里將Foo.prototype.propA設置為一個對象,來防止因基本類型的值比較方式導致結論誤差

o1.constructor === Foo // true

Foo.prototype.propA = {}
o1.propA // {}

o1.propA === o1.__proto__.propA // true
o1.__proto__.propA === Foo.prototype.propA // true

二、原型鏈

在介紹何為prototype以及__proto__后,接下來就開始介紹原型鏈了。仍以之前使用的例子來進行原型鏈的介紹

function Foo(){}
const o1 = new Foo()

(一)、實例化關系

首先一起來分析例子的實例化關系。可在Chrome中測試如下代碼

o1.constructor === Foo // true
Foo.constructor === Function // true
Function.constructor === Function // true

根據驗證結果可分析出如下圖結論

圖片圖片

  1. o1的數據類型是對象,是函數Foo的實例化
  2. Foo的數據類型既是函數也是對象,也是Function的實例化
  3. Function既是函數也是對象,其是自身Function的實例化

(二)、獨有屬性分析

在實例化關系的基礎上,繼續分析每一級的屬性關系。其中綠色代表函數獨有屬性,紅色代表對象獨有屬性

圖片圖片

  1. o1的數據類型為對象,擁有獨有屬性__proto__,由于prototype是函數獨有屬性,所以o1上的prototype為undefined
  2. Foo的數據類型既是函數也是對象,所以其同時擁有屬性prototype和__proto__
  3. Function的數據類型既是函數也是對象,所以其同時擁有屬性prototype和__proto__

(三)、隱式原型引用關系

[!NOTE]

對象的隱式原型(__proto__)屬性指向其構造函數(constructor)的原型對象(prototype)

圖片圖片

  1. o1.__proto__指向其構造函數Foo的原型對象( prototype )
  2. Foo.__proto__的指向其構造函數Function的原型對象( prototype )
  3. 由于Function的構造函數是其自身,所以Function.__proto__指向其自身的原型對象( prototype )

由于函數的原型對象( prototype )屬性的數據類型為對象,因此同樣具有對象的獨有屬性__proto__。如下圖

圖片圖片

默認情況下,對象隱式原型( __proto__ )指向其構造函數的原型對象( prototype ),那么Foo.prototype和Function.prototype的構造函數有指向哪里呢?

[!NOTE]

所有函數的原型對象( prototype )的構造函數均指向其自身

可通過以下測試代碼進行驗證

Foo.prototype.constructor === Foo // true
Function.prototype.constructor === Function // true

內置函數對象的原型對象( prototype ),其隱式原型( __proto__ )也指向其自身

RegExp.prototype.constructor === RegExp // true
Date.prototype.constructor === Date // true
Map.prototype.constructor === Map // true
Array.prototype.constructor === Array // true
Number.prototype.constructor === Number // true
Object.prototype.constructor === Object // true

然而一些內置對象由于其沒有函數特征,所以其原型對象( prototype )屬性為undefined,其自身的constructor指向Object。

Math.prototype // undefined
Math.constructor === Object // true

JSON.prototype // undefined
JSON.constructor === Object // true

言歸正傳,由于所有函數的原型對象( prototype )的構造函數均為其自身,則如若Foo.prototype.__proto__指向其構造函數的prototype,即Foo.prototype.__proto__指向Foo.prototype。那么原型鏈的查找將進入無限循環。為了避免這個問題,則將所有函數原型對象( prototype )的隱式原型(__proto__)均指向Object.prototype。

圖片圖片

可通過以下代碼進行驗證:

Foo.prototype.__proto__ === Object.prototype // true
Function.prototype.__proto__ === Object.prototype // true

這里欠缺的有兩個點:

  1. Object既是函數也是對象,所以其擁有對象的獨有屬性( __proto__ ),那么其隱式原型( __proto__ )指向哪里
  2. Object.prototype的數據類型為一個對象,如果其隱式原型( __proto__ )仍指向Object.prototype,那么原型鏈的查找將進入無限循環,那么其指向哪里

圖片圖片

針對第1點,Object自身既是函數又是對象,其作為對象的獨有屬性隱式原型( __proto__ )應指向其構造函數的原型對象( prototype )。Object對象的構造函數為Function,所以其隱式原型( __proto__ )指向Function.prototype。

可通過以下測試代碼進行驗證:

Object.constructor === Function // true
Object.__proto__ === Function.prototype // true

因此其指向關系如下圖:

圖片圖片

針對第2點,文章起始什么是原型鏈已經給出了定義。

原型對象也有一個自己的原型,層層向上直到一個對象的原型為 null

因此其最終指向為null

圖片圖片

三、總結:

對象通過隱式原型( __proto__ )屬性指向其構造函數的原型對象( prototype ),進而通過原型對象( prototype )的隱式原型( __proto__ )屬性指向更高層級的原型對象( prototype ),最終指向null而停止所形成的鏈條,則稱其為原型鏈。

責任編輯:武曉燕 來源: 大轉轉FE
相關推薦

2023-12-22 19:59:15

2021-08-04 16:06:45

DataOps智領云

2018-09-28 14:06:25

前端緩存后端

2022-09-22 09:00:46

CSS單位

2025-04-03 10:56:47

2022-11-06 21:14:02

數據驅動架構數據

2019-12-17 08:16:04

JavaScriptthis編程

2020-06-23 08:41:47

JavaScript開發技術

2018-03-17 09:00:21

大數據 區塊鏈

2023-11-27 17:35:48

ComponentWeb外層

2023-05-20 17:58:31

低代碼軟件

2022-07-05 06:30:54

云網絡網絡云原生

2022-07-26 00:00:03

語言模型人工智能

2021-12-29 18:00:19

無損網絡網絡通信網絡

2022-10-20 08:01:23

2022-12-01 17:23:45

2020-12-30 09:05:24

架構微內核系統

2021-02-05 05:26:33

字節ASCII控制

2017-05-04 20:29:12

HTTP服務器TCP
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 黄色三级在线播放 | 中文字幕91| 久久99深爱久久99精品 | 成人伊人| 亚洲精品女人久久久 | 欧美日韩国产在线观看 | 国产精品久久久久久久久图文区 | 国产精品国产成人国产三级 | 精品视频在线免费观看 | 成人免费视频在线观看 | 国产区免费视频 | 日韩精品一区二区三区免费视频 | 成人亚洲精品 | 一区二区三区中文字幕 | 免费看大片bbbb欧美 | 久久精品99| 99热精品在线 | 四虎影院久久 | 久久久久国产精品 | 丁香六月激情 | 久久久精品高清 | av久久 | 欧美另类视频在线 | 亚洲免费一区 | 国产高清视频在线播放 | 欧美视频一区二区三区 | 日韩在线中文 | 凹凸日日摸日日碰夜夜 | 久久久高清 | 狠狠操你 | 奇米久久 | 超碰av人人 | 国产美女福利在线观看 | 日韩三级在线观看 | 网色 | 一区视频在线 | 欧美一级免费看 | 国产欧美精品一区二区三区 | 第一av| 国产精品久久久久久吹潮 | 日韩精品成人av |