JavaScript 中除了基礎(chǔ)類型外的數(shù)據(jù)類型,都是對(duì)象(引用類型)。但是由于其沒有 類(class,ES6 引入了 class,但其只是語法糖)的概念,如何將所有對(duì)象聯(lián)系起來就成立一個(gè)問題,于是就有了原型和原型鏈的概念。
每個(gè)實(shí)例對(duì)象( object )都有一個(gè)私有屬性(稱之為 __proto__ )指向它的構(gòu)造函數(shù)的原型對(duì)象(prototype?)。該原型對(duì)象也有一個(gè)自己的原型對(duì)象( __proto__ ) ,層層向上直到一個(gè)對(duì)象的原型對(duì)象為?null。根據(jù)定義,null?沒有原型,并作為這個(gè)原型鏈中的最后一個(gè)環(huán)節(jié)
上面是?MDN里有關(guān)原型鏈知識(shí)?的摘錄,什么意思?讓我們來解釋一下
事實(shí)上 JavaScript 所有數(shù)據(jù)都可以以對(duì)象的形式表現(xiàn):由于函數(shù)是對(duì)象,我們可以用構(gòu)造函數(shù)的方法使得 Number、Boolean、String 變成對(duì)象。
下面以 Number 為例 (其他類型也一樣)
可以用 var 基本類型 = new 對(duì)應(yīng)基本類型的函數(shù)() 的方法創(chuàng)建一個(gè)新函數(shù)
var n = new Number() 創(chuàng)建一個(gè) Number 函數(shù),其是一個(gè)對(duì)象
這里的 n 就是 Number 的實(shí)例對(duì)象,可以看到 n 里面有一個(gè) __proto__ 指向 Number 所指向的原型對(duì)象(也是 n 自己本身的原型對(duì)象),Number 為 n 的構(gòu)造函數(shù),它通過 prototype 指向自己的原型對(duì)象,而后又可以通過 constructor 指向回 Number 本身;
而 Number 函數(shù)也有一個(gè) __proto__ 指向 Object 這個(gè)構(gòu)造函數(shù)的原型對(duì)象,Object?通過?prototype 指向自己原型對(duì)象 ;
Object 函數(shù)沒有 __proto__,證明其已經(jīng)到達(dá)最后的屬性層,他的?__proto__ 指向?yàn)?null。
即
以上一整個(gè)原型與原型層層相鏈接的過程即為原型鏈
其可以將公用屬性存放在同一原型層中,實(shí)現(xiàn)繼承、節(jié)省內(nèi)存空間等。
當(dāng)您訪問實(shí)例的屬性時(shí),JavaScript 首先會(huì)檢查它們是否直接存在于該對(duì)象上,如果不存在,則會(huì) [[Prototype]] 中查找。這意味著你在 prototype 中定義的所有內(nèi)容都可以由所有實(shí)例有效共享,你甚至可以稍后更改部分 prototype,并在所有現(xiàn)有實(shí)例中顯示更改(如果需要)。
通過以上例子我們可以得到下面兩個(gè)“公式”
var 對(duì)象 = new 函數(shù)()
對(duì)象.__proto__ === 對(duì)象的構(gòu)造函數(shù).prototype
我們已經(jīng)知道
var n = new Number()
n.__proto__ === Number.prototype //true
那么 Number.__proto__ ?
Number 的構(gòu)造函數(shù)是 Function,即 Number 是 Function 的實(shí)例
即有 Number.__proto__ === Function.prototype
那么同理
var object = new Object()
object.__proto__ === Object.prototype
Object.__proto__ === Function.prototype
再進(jìn)一步推斷
var function = new Function()
function.__proto__ === Function.prototype
Function.__proto__ === Function.prototype
本文主要用于個(gè)人學(xué)習(xí)使用,如有侵權(quán)請(qǐng)聯(lián)系我刪除。
參考及推薦: