JavaScript里的原型與原型鏈

目錄

- 全局對象

- 簡單類型與對象

- Number、Boolean、String、Object四個對象

- (共用屬性)原型

- __proto__與 prototype

- 燒腦的等式

- 奇葩的Function


全局對象Window

ECMAScript 規(guī)定全局對象叫做 global,但是瀏覽器把 window 作為全局對象(瀏覽器先存在的)


注:

- window對象中的所有方法都可以省去window,alert()方法可以寫成window.alert(),或者省去window,直接寫做alert()

- 瀏覽器自己加的屬性,因為沒有標準,所以瀏覽器上呈現(xiàn)的效果是不一樣的




簡單類型與對象

聲明一個數(shù)值類型的變量


下面通過內存圖查看它們之間的區(qū)別


它們在內存中的存儲方式是不同的,n1是直接聲明簡單的數(shù)據(jù)類型(number),存儲在stack棧內存中,而n2是聲明了一個對象stack內存中存儲著該對象的內存地址,對象的內容存儲在heap堆內存中。

但是在平常寫代碼的時候我們沒有使用n2的寫法,也可以使用valueOf() 方法 和toSting()方法,這里有一段黑歷史(JS之父為了滿足Boss的需求,為了讓JavaScript長得像Java),可以自行google

原因是:JS使用妙計:臨時轉換(用完了就沒了),如果你使用n1的寫法,調用了了如valueOf方法,那么JS會創(chuàng)建一個臨時的對象,然后調用該對象的方法,調用結束后臨時對象就會被垃圾回收掉。

踩坑時間到:

答案:n.xxx = 2;這句話不會報錯,執(zhí)行這句話時,JS會創(chuàng)建一個臨時對象,為臨時對象添加屬性,執(zhí)行這句話后,臨時對象就會被回收,如果再執(zhí)行n.xxx,結果是undefined,因為給n添加完屬性后臨時對象就會被回收,n本質上還是一個數(shù)值,沒有臨時對象,再去重新創(chuàng)建一個新的對象,里面沒有這個屬性(有個這屬性的對象已經(jīng)被刪了)。


Number對象


如:


注:number類型的的toString方法可以加參數(shù),表示按照什么進制來解析(不加參數(shù)默認按十進制解析),如:





String對象


如:





Boolean對象

介紹一個兩種不同的賦值方法下容易出錯的地方。


注:

f1和f2的值都是false,但是f2是對象,一切對象(不論是否是空對象)都是truey,所以使用if判斷語句,會將f2轉化為了true,打印出2




Object對象

Object對象,兩種賦值方法是一樣的,沒有任何區(qū)別。

注:


為什么obj1不恒等于obj2???同樣都是空獨享,但是它們在stack棧內存中存儲的內容是heap堆內存中的地址,每個對象的內容在heap內存中的地址是不會一樣的,所以對象與對象一般都是不相等的。(除非你將一個對象的內存地址復制給另一個對象)




原型/共用屬性(重點!?。。?/h1>

所有對象都有 toString 和 valueOf 屬性,那么我們是否有必要給每個對象一個 toString 和 valueOf 呢?答案是不需要的。因為JS每次聲明一個對象都要寫一次這些方法這樣寫的話會非常占用內存,而且內存還那么,所以JS 的做法是把所有的對象共用的屬性全部放在heap堆內存的一個對象(共用屬性組成的對象),然后讓每一個對象的__proto__存儲這個「共用屬性組成的對象」的地址。而這個共用屬性,就是傳說中的原型

原型的目的:可以減少不必要的內存浪費


根據(jù)下面內存圖分析原型

- __proto__就是這些共用屬性的引用。

- 聲明Number對象、String對象、Boolean對象時,如聲明Number對象,在stack棧內存中存儲著該對象的內存地址,對象的內容存儲在heap堆內存中。對象的內容里面有__proto__,它指向的Number的共用屬性(Number.prototype)。

某些等式:


其他對象也可以得出類似的等式

__proto__?與 prototype


上圖是我們還沒有寫代碼的時候,瀏覽器都已經(jīng)初始化好了,prototype是瀏覽器提前準備好的。

當我們寫代碼的時候:



我們創(chuàng)建的對象的__proto__會用來指向原有的String對象,使得我們可以調用String對象的公有屬性。

總結:

【1】__proto__是某對象的共用屬性的引用,是為了用戶使用其共用屬性中的方法而存在的 。(使用的)

【2】prototype 是瀏覽器寫的,本身就存在,是某對象的共同屬性的引用,為了不讓對象的共用屬性因沒有被調用而被垃圾回收而存在。(防止回收)


一些燒腦的等式

通過var 對象 = new 函數(shù);推出其他燒腦的等式





奇葩的Function

我們經(jīng)過上面的推導,發(fā)現(xiàn)Function,他即是函數(shù),也是對象,所以他有函數(shù)的prototype,也有對象的__proto__,即Function.prototype 與Funciton.__proto__互相引用。

注:

Object.__proto__ === Function.prototype,因為 Function 是 Object 的構造函數(shù)。

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

相關閱讀更多精彩內容

  • 前言:原型與原型鏈這兩個名詞毋庸置疑聽起來是很高大上的,以前總是出現(xiàn)在傳說中,這兩天看了教程,準備介紹一下這傳說中...
    EnochQin閱讀 735評論 0 3
  • 前言:原型與原型鏈兩個名詞對于大部分的前端初學者來說,對這兩個概念很模糊,無從入手,而且還可能會一臉懵逼,本人不才...
    xyyojl閱讀 2,716評論 0 29
  • 參考JavaScript深入之從原型到原型鏈和阮一峰的博客:Javascript繼承機制的設計思想 Why??? ...
    如夢初醒Tel閱讀 1,478評論 0 10
  • 前言:原型與原型鏈兩個名詞對于大部分的前端初學者來說,對這兩個概念很模糊,無從入手,而且還可能會一臉懵逼,本人不才...
    一只小前端閱讀 1,034評論 0 16
  • 本文將從全局對象引入,分別介紹Number、Boolean、String、Object四個對象,然后再詳述原型的相...
    壹如既往的活著閱讀 429評論 0 0

友情鏈接更多精彩內容