js中的原型與原型鏈

js中的原型與原型鏈

來自專欄小谷悠悠伴我行4 人贊了文章

公用屬性(原型)

用String賦值的變數s1,她的__proto__指向了String共有屬性(原型),String的原型裡面還有__proto__的原型指向Object共有屬性,Object共有屬性最後指向了null,結構圖如下:

Numer的共有屬性:Number.prototype

Object的共有屬性:Object.prototype

String的共有屬性:String.prototype

Boolean的共有屬性:Boolean.prototype

上面的代碼Object.prototype就是上邊結構圖的Object的共有屬性(原型),o1的__proto__指向Object里的原型,所以是true

n1的下劃線原型指向的是Number的原型,然後Number原型裡面的下劃線原型指向Object的原型,所以就可以寫成

n1.__proto__.__proto__ === Object.prototype或者:Number.prototype.__proto__ === Object.prototype

注意:prototype是瀏覽器自動生成的,你就算不寫代碼也有

上面的圖當你什麼代碼也不寫的時候,打開瀏覽器也會有一個window對象,而window對象里有Number、Object、String、Boolean這幾個全局函數,又因為函數也是對象,所以他們再次將內容存放到一個堆里,又因為是函數所以有prototype的原型,分別指向自己對應的類型,而最後prototype也是一個對象,只要是對象就有__proto__這個下劃線的原型,通過他指向了Object公用屬性。就拿Number這個全局函數來舉例

上面沒有執行任何操作,直接列印了Number這個函數,它裡面的prototype就指向了Number的公用屬性,而她的prototype下面還有一個下劃線的原型指向了Object的公用屬性。

上面的代碼,var 後面的肯定是對象,new後面的是函數對象

對象的下劃線原型指向該實例對象的構造函數的原型也就是說:

var n = new Object();n.__proto__ === Object.prototype//new後面的就是構造函數名,以new方法生成的函數就是構造函數

Object.__proto__ =null

數組的構造函數是 Array

函數的構造函數是 Function

正則的構造函數是 RegExp

數組、函數、正則都是對象。

而String,Number,Boolean,Object,Function這幾個是全局函數,所以它的構造函數就是Function,故指向Function.prototype:

這裡最需要注意的是Function的構造函數就是Function,只有它的__proto__是指向自己的:

另外判斷一個對象的構造函數可以用

1.console.log(xxx.constructor),但是注意xxx只能是單獨的對象就是xxx裡面不可以接prototype或者__proto__

第一個Function.constructor是可以正確判斷的,但Function.prototype.constructor就不能,它顯示的也是Function可實際上它的構造函數是Object。另外判斷一個構造函數是什麼其實上述方法並不可取,因為不排除有人為改變構造函數的可能,所以暫且只需記住就行,另外只要是(對象.prototype)或者(對象.__proto__)作為對象的時候他們的構造函數都是Object(這裡排除特例)

2.實例對象.constructor(構造器里的prototype始終指向構造函數本身)

實例對象的__proto__和構造函數中的prototype相等--->true

因為實例對象是通過構造函數來創建的,構造函數中有原型對象prototype

實例對象的__proto__指向了構造函數的原型對象prototype

只要是對象就有__proto__原型

又因為prototype也是對象,所以,prototype也有__proto__

對象由構造函數創建的

函數也是對象

函數由Function創建的

對象的__proto__等於創建者的prototype

prototype上有個屬性constructor 指向創建者(構造函數)

關係圖如下:

進一步說明實例對象.__proto__===構造函數.prototype

var a = [];

列印出數組的結構,從下面的代碼分析可證明上面:

從上年可以看出a的__proto__後面是Array(0),它裡面的構造器(constructor)指向的構造函數是Array,而它裡面的prototype後面的也是Array(0),指向的構造函數也是一樣的,所以是true

對上面的代碼進一步分析,因為Array.prototype也是一個對象,只要是對象就有_proto_,所以

所以上面代碼也是true

另外:

因為a._proto_===Array.prototype,所以上面的式子等價於

另外在瀏覽器中,prototype.__proto__的構造函數,應該在prototype的第一子級下查看,而不是在它的構造器里的__proto__查看:

上面的代碼Array.prototype.__proto__.constructor就應該是Object

推薦閱讀:

大前端開發環境搭建
棒棒少年團第一期分享交流活動VUE以及前端入門問題
vue生命周期和鉤子函數
web前端三劍客之一jQuery
yarn 安裝使用小記

TAG:前端開發 | 前端工程師 | 原型設計 |