一、內(nèi)存圖
1.JavaScript 將從瀏覽器分到的內(nèi)存分為代碼區(qū)和數(shù)據(jù)區(qū)兩個區(qū)域來保存數(shù)據(jù),其中數(shù)據(jù)區(qū)又分為棧(Stack)和堆(Heap)。
2.代碼區(qū)保存著提交了的代碼,而數(shù)據(jù)區(qū)的使用比較復(fù)雜。對于簡單類型的數(shù)據(jù),在棧內(nèi)存中保存數(shù)據(jù)的值;對于復(fù)雜類型的數(shù)據(jù),Stack中保存一個指向Heap的地址,這個地址就是Heap內(nèi)存中儲存相應(yīng)數(shù)據(jù)的地方。

參考圖
二、原型與原型鏈
1.全局屬性
瀏覽器默認(rèn)的全局對象為 window,ECMAScript 中叫g(shù)lobal, window 的屬性分為兩類
- ECMA Script 規(guī)定: parseInt , parseFloat , Number() ,
String() , Boolean() , Object()等。 - 瀏覽器私有(以 chrome 為例): alert , prompt , confirm , console , document(DOM 規(guī)范由 W3C 制定) , history 等。
2.簡單類型與對象的區(qū)別(以 Number 為例)
- Number 以
var a = 1為例,分析當(dāng)輸入代碼時,瀏覽器做了什么。
(1)使用var a = 1;var a = new Number(1)聲明的是不同類型的數(shù)據(jù)。
用var a = 1聲明時只是保存一個數(shù)值在 Stack 中,用var a = new Number(1)聲明的是一個 number 對象,但是為了更方便的操作 Number 的函數(shù),對var a = 1做了一個臨時轉(zhuǎn)換。
(2)當(dāng)var a = 1聲明 a = 1 ,在 Stack 中存了 1 。運(yùn)行a.toString()時,生成一個 tamp 臨時對象(保存在我們不知道的地方,假設(shè)保存在 Stack),對象地址為 ADDR1 指向 Heap中的 ADDR1,ADDR1 中包含了 number 類型的默認(rèn) API。這種情況下,var a = 1;a.toString()瀏覽器會去調(diào)用 tamp.toString(),將 1 變?yōu)?'1' 并將 '1' 作為a.toString()的值返回,之后刪除 tamp。
(3)對 tamp 操作一次后即刪除 tamp,再次操作 a 則建立新的 tamp。
(4)其他簡單類型與 number 相似,只是有不同的默認(rèn) API。
tamp 為臨時對象 - Object
使用var o = {}var m = new object()聲明的是相同類型的數(shù)據(jù)。
o 與 m 類型相同,但不相等
3.原型與原型鏈
(1)公用屬性(原型):每一個數(shù)據(jù)類型有自己本身的公用屬性,同時有和其他數(shù)據(jù)類型公用的屬性,如 valueOf 、toString等。
(2)為節(jié)省內(nèi)存,將數(shù)據(jù)的公用屬性放在一個對象里,當(dāng)需要用到公用屬性時再對其進(jìn)行引用。
(3)公用屬性的引用,以一個對象為例。
a. 對象的公用屬性保存在 Object 的 prototype 中,可使用 obj.--proto-- 引用。注意,obj.--proto-- === Object.prototype 。
圖中紅線箭頭鏈即為原型鏈
b. object 的公用屬性是所有對象的公用屬性。
c. prototype 是瀏覽器準(zhǔn)備好的數(shù)據(jù),--proto-- 指向 prototype。
(4)無代碼狀態(tài)下的瀏覽器

紅色為輸入代碼后的動作
a. String.prototype 是 String 的公用屬性的引用,s.--proto-- 是對String 的公用屬性的引用。
var 對象 = new 函數(shù)()
對象.--proto-- === 函數(shù).prototype


