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 安裝使用小記