什么是原型和原型鏈?
在講這個之前,我們先把這個名詞忘掉,不要試圖從字面意思去理解這個詞,它只是幾個漢字,我們可以把這個看成[ab]和[abc]。
在這之前我們先來了解一些必要的知識
數據類型
js里 數據類型分為 7 種:
string? number? null undefined? object Boolean??symbol??
數據類型又分兩種:簡單數據類型 復雜數據類型 。 復雜類型是由簡單類型組成的。
復雜數據類型只有object
內存:棧內存 堆內存
這個就不從頭開始介紹了,我們可以簡單的把這個想象成這個虛擬的空間, 我們把這個分為兩個部分:棧內存部分,堆內存部分。
一般的,當我們創建一個新的對象時,簡單的數據類型的值直接存在棧內存中。 復雜數據類型的值存在堆內存中,但是在棧內存中會存一個地址,好讓我們能在堆內存中找到它。
1? 與 new Number(1) 的區別
當我們 var a1 = new Number(1)? ?js創建了一個對象(哈希),除了一個PrimitiveValue
同時還有一個可以點開的屬性 __proto__:Number, 這個屬性中包含了另一些屬性
這些屬性中有一些我們可以看懂的 toString? ?它指向一個toString函數 和一個 valueOf屬性和它的函數
我們可以調用這些方法得到一些返回值
當我們 用var a2 = 1 創建一個對象時候 我們同樣可以調用? toString() valueOf() ,這是為什么呢?
因為 當我們var a2 = 1 寫下這行代碼的時候 它還只是個簡單類型 它的值 直接存在棧內存中?
但我們寫下 a2.toString()的時候 它就會被一個臨時對象(temp)替代? 這個對象 跟 temp = new Number(1)? 完全相同
這樣它就能想a1一樣 調用這些屬性,當你完成這些操作得到返回值時候這個臨時對象就會被銷毀。
所以 var a = 1? 和 var a = num Number(1) 唯一的區別就是? 后者比前者寫起來麻煩 除此之外沒有任何區別。
共用屬性
我們再 var b = new Number(2) 跟 a1 比較
我們可以看到? 除了PrimitiveValue 不一樣之外 其他部分一樣? 。
因此我們可以知道__proto__:Number? 就是number 的共用屬性
JS 內存是很稀缺的? js不可能每次創建一個number 對象 就寫一遍這個屬性? 這樣非常浪費空間
所以JS 把這些共有屬性存放在一個地方? 當我們需要的時候 就通過__proto__:Number 找到它。
我們會注意到 在__proto__:Number 里面 還有一個__proto__:Object? ? 這個里面 是所有對象的共有屬性?
__proto__:Object? 里面還會指向其他的共有屬性嗎 沒有了?__proto__:Object 里面的?__proto__ 指向的是null
這些共用屬性是哪里來的
這些共有屬性不是你穿件對象時才出現的而是你一打開瀏覽器就存在的
當我們打開瀏覽器 ,瀏覽器就會自動創建一個全局對象global(window)? window對象會創建很多方法? 其中就包括 number() String()等等
這些不同的方法 構造了 不用類型的共用屬性? 然后供我們調用 這些構造出來的共用屬性 我們就叫做 原型(prototype)
__proto__? 為了引用共用屬性用的。 我們把一層一層引用共用屬性的鏈接 叫做 原型鏈
對象的?__proto__ 指向的就是 創建這個對象的 函數構造的prototype