原型與原型鏈

全局對象window

ECMAScript 規(guī)定全局對象(函數(shù)也是對象)叫做 global,但是瀏覽器把 window 作為全局對象(瀏覽器先存在的)
window 就是一個哈希表,有很多屬性。
window 的屬性就是全局變量。
這些全局變量分為兩種:
一種是 ECMAScript 規(guī)定的
global.parseInt
global.parseFloat
global.Number
global.String
global.Boolean
global.Object
一種是瀏覽器自己加的屬性
window.alert
window.prompt
window.comfirm
window.console.log
window.console.dir
window.document
window.document.createElement
window.document.getElementById
所有 API 都可以在 MDN 里找到詳細的資料(全局變量前的window或global可以省略)。

全局函數(shù)

  1. Number
    var n = new Number(1) 創(chuàng)建一個 Number 對象
    Number('1') 與 new Number(1) 的區(qū)別是什么?看內(nèi)存圖

數(shù)字1是普通數(shù)據(jù)類型直接放在stack中,而new Number(1)是對象,stack中存的是heap的地址,heap里存著對象的Hash表。
但是n1 = 1,n1也可以調(diào)用Number對象的函數(shù)如toString(),這是為什么呢?


因為當(dāng)n1調(diào)用toString時,系統(tǒng)臨時構(gòu)造了一個對象n1,用完后再把它垃圾回收,這是一個臨時的轉(zhuǎn)換,用完后對象就沒了。


例題:

n.xxx = 2時, n構(gòu)造了一個臨時對象并為對象添加了一個鍵值對,但執(zhí)行完這句后,該臨時對象就被抹殺掉了,n還是數(shù)字1,所以n.xxx是undefined。

  1. String
    var s = new String('hello') 創(chuàng)建一個 String 對象
    string('hello')與 new String('hello') 的區(qū)別是什么?看內(nèi)存圖

  2. Boolean
    var b = new Boolean(true) 創(chuàng)建一個 Boolean對象
    Boolean(true) 與 new Boolean(true) 的區(qū)別是什么?看內(nèi)存圖



    f2是對象,f2的stack中存的是地址,它當(dāng)然和f=false不相等,所以f2不是falsy值是true。

js中的6個falsy值:

  1. Object
    var o1 = {}
    var o2 = new Object()



    o1 和 o2 沒區(qū)別,但是o1和o2不相等,因為stack里存的地址是不相等的。

詳解全局函數(shù)




以上四個全局函數(shù)構(gòu)造的對象都有一些公有的屬性,比如:toString()、valueOf()。不可能每聲明一個對象都在對象里加上這些公有屬性,這樣內(nèi)存太浪費,Js的做法是把共用屬性放在一起,然后每個對象都有一個鍵名為proto的鍵,它的值就是這些共用屬性所在的內(nèi)存地址。
但是Number、String和Boolean這三個全局函數(shù)都有一些自己的屬性,比如Number函數(shù)有toFixed()、toExponential()、toString(16)
等等這些只有Number函數(shù)才有的屬性,并不屬于Object共有的屬性。所以Js的方法是在Number對象的proto中放Number共有屬性的地址,在Number共有屬性對象的proto中放對象共有屬性的地址,對象Object的proto中放的是Null,如下圖所示:

但是這樣也存在一個問題,如果String、Number、Bool和Object的共用屬性沒有被引用不就被當(dāng)作垃圾回收了嘛,所以系統(tǒng)必須有對象一直在引用著這些共用屬性。




當(dāng)沒寫任何代碼時,系統(tǒng)也內(nèi)嵌了全局對象window,window對象中又有Number、Object、String、Boolean這些屬性,這些屬性引用的地址中存放著這么屬性的默認返回值以及prototype,其中prototype指向各自的共有屬性。這都是系統(tǒng)初始化好的,而當(dāng)我們創(chuàng)建一個變量時,創(chuàng)建的變量中有一個proto指向共用屬性,所以proto和prototype指向的地方是一樣的;也可以說String.prototype防止公用屬性被垃圾回收的,s.proto是s要用到這些公用屬性而建立的引用。



疑點解釋:

1.Object.proto === Function.prototype // true

Object是函數(shù)對象,是通過new Function()創(chuàng)建,所以O(shè)bject.proto指向Function.prototype。

2.Function.proto === Function.prototype // true

Function 也是對象函數(shù),也是通過new Function()創(chuàng)建,所以Function.proto指向Function.prototype。
因為function既是對象又是函數(shù),所以你它既有proto又有prototype,它們都指向function的共用屬性。

3.Function.prototype.proto === Object.prototype //true

其實這一點我也有點困惑,不過也可以試著解釋一下。
Function.prototype是個函數(shù)對象,理論上他的proto應(yīng)該指向 Function.prototype,就是他自己,自己指向自己,沒有意義。
JS一直強調(diào)萬物皆對象,函數(shù)對象也是對象,給他認個祖宗,指向Object.prototype。Object.prototype.proto === null,保證原型鏈能夠正常結(jié)束。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容