準(zhǔn)備寫點(diǎn)亂七八糟的文章,對JavaScript的胡扯
賦詩一首:
對象本無根促煮,
類型亦無形邮屁。
本來無一物,
何處惹塵埃菠齿?
一佑吝、JavaScript的內(nèi)存模型
JavaScript的本質(zhì)是一個對象,一個對象可以包含多個屬性绳匀,對象的屬性可以分為直接量和對象兩種類型芋忿,而對象又分為Object對象和function對象兩種類型。
按照數(shù)據(jù)類型劃分:
- 簡單數(shù)據(jù)類型
- number
- string
- boolean
- 特殊數(shù)據(jù)類型
- null
- undefined
- 復(fù)雜數(shù)據(jù)類型
- object
- Object對象
- function對象
- object
直接量和對象的兩種類型的屬性在內(nèi)存中保存方式不同(跟Java中的類似)
-
直接量:直接用兩塊內(nèi)存分別保存屬性名和屬性值
image -
對象:需要三塊內(nèi)存疾棵,分別保存屬性名戈钢、屬性地址和屬性內(nèi)容
image
對于對象類型的屬性來說,屬性名知識指向了保存對象的內(nèi)存地址陋桂,而不是執(zhí)行實(shí)際的對象逆趣,代碼演示如下:
function F(){
this.v = 1;
}
var f1 = new F();
var f2 = f1;
console.log(f2.v);
f2.v = 2;
console.log(f1.v);
f1 = null;
console.log(f2.v);
代碼的執(zhí)行圖解:
我們一直都說JavaScript是腳本語言,在瀏覽器中解釋執(zhí)行的嗜历,不應(yīng)該有自己的內(nèi)存模型,其實(shí)不是這樣的抖所。無論編譯語言還是解釋型語言梨州,他們的變量、函數(shù)田轧、對象等數(shù)據(jù)都是保存在內(nèi)存當(dāng)中的暴匠,使用時需要通過變量名在指定地方找到對應(yīng)的具體內(nèi)容,然后再進(jìn)行實(shí)際操作傻粘。
二每窖、在JS中函數(shù)是如何執(zhí)行的
函數(shù)我們之前已經(jīng)都接觸過了,函數(shù)無非有兩部分:數(shù)據(jù)和對數(shù)據(jù)的操作弦悉。數(shù)據(jù)有分為外部數(shù)據(jù)和內(nèi)部數(shù)據(jù)窒典。對于外部數(shù)據(jù)我們先不進(jìn)行說明,這里主要是說函數(shù)稽莉,內(nèi)部數(shù)據(jù)有分為參數(shù)和變量兩個部分瀑志。
參數(shù)(形參):在函數(shù)每次執(zhí)行的時候參數(shù)都會被賦予一個新的數(shù)值;
變量(局部變量):每次都會設(shè)置為一個相同的初始值;
-
函數(shù)的變量和參數(shù)是如何保存的呢劈猪?
函數(shù)在每次執(zhí)行之前都會新建一個參數(shù)數(shù)組和一個變量數(shù)組(當(dāng)然也可以合并為一個數(shù)組昧甘,而通常會使用棧來實(shí)現(xiàn)),然后將調(diào)用時所傳遞的參數(shù)設(shè)置到參數(shù)數(shù)組中战得,而變量數(shù)組在每次執(zhí)行都具有相同的內(nèi)容充边。簡單的數(shù)據(jù)會直接保存在數(shù)組當(dāng)中,而復(fù)雜的數(shù)據(jù)常侦,數(shù)組只是保存地址痛黎,具體的數(shù)據(jù)保存在堆中。
imagefunction paramTest(p1){ var message = "Hello World"; console.log(p1); for(var i in arguments){ console.log(arguments[i]); } } //函數(shù)的調(diào)用 paramTest("a","b","c"); //輸出結(jié)果為: a a b c
我們使用了Chrome的調(diào)試刮吧,函數(shù)在執(zhí)行時會將參數(shù)p1和函數(shù)中所用到的變量messag湖饱、i方法相同的地位,即在函數(shù)內(nèi)部執(zhí)行的時候不會區(qū)分是參數(shù)還是變量杀捻。在JS的函數(shù)中井厌,會自動創(chuàng)建一個名字為
arguments
的內(nèi)部變量,然后將所有的參數(shù)的地址保存到其中致讥。arguments 類似數(shù)組對象仅仆,可以通過它來獲取函數(shù)調(diào)用時所傳遞的參數(shù)。imageparamTest方法首先打印了p1的值垢袱,然后遍歷打印arguments中所有的參數(shù)的值墓拜,可以看出參數(shù)p1的值和arguments[0]的值是一樣的,函數(shù)的參數(shù)按照順序依次保存在arguments變量中请契,在調(diào)用函數(shù)時傳入?yún)?shù)的個數(shù)也可以和定義時不一樣咳榜,所以說JS中不存在同名函數(shù)的重載方法。
-
在函數(shù)定義的變量時函數(shù)級作用域而不是塊級作用域
function scopeTest(){ if(true){ var message = "Hello World"; } console.log(message); } //函數(shù)的調(diào)用 scopeTest(); //輸出結(jié)果為:Hello World
這里的message是在if語句塊中定義的爽锥,但是在if語句外部依然可以進(jìn)行調(diào)用涌韩。
在JS中的方法執(zhí)行時會將其自身所有使用var定義的變量統(tǒng)一放到前面介紹的變量數(shù)組當(dāng)中,所以在一個函數(shù)中氯夷,所有使用var定義的變量都是同等地位的