淺析JavaScript中的變量復(fù)制、參數(shù)傳遞和作用域鏈
今天在看書的過程中,又發(fā)現(xiàn)了自己目前對(duì)Javascript存在的一個(gè)知識(shí)模糊點(diǎn):JS的作用域鏈,所以就通過查資料看書對(duì)作用域鏈相關(guān)的內(nèi)容進(jìn)行了學(xué)習(xí)。今天學(xué)習(xí)筆記主要有這樣幾個(gè)關(guān)鍵字:變量、參數(shù)傳遞、執(zhí)行環(huán)境、變量對(duì)象、作用域鏈。
1.變量
變量需要注意的有兩點(diǎn):變量聲明和復(fù)制變量值。
變量聲明肯定大家都很熟悉,在JS中我們都是通過 var 關(guān)鍵字進(jìn)行變量聲明的。JS中規(guī)定,通過var聲明的變量會(huì)被添加到最近的環(huán)境中,如果聲明并且初始化一個(gè)變量沒有用到var關(guān)鍵字,這個(gè)變量會(huì)被添加到全局環(huán)境中。
關(guān)于復(fù)制變量值,因?yàn)樽兞康念愋筒煌瑥?fù)制的過程也不同。如果變量是一個(gè)基本類型的變量的話,復(fù)制變量值時(shí)會(huì)給新復(fù)制出的變量分配新的空間,兩個(gè)變量值互不影響;如果變量是一個(gè)引用類型的話,復(fù)制的操作其實(shí)是讓兩個(gè)變量指向了同一處內(nèi)存空間,修改其中一個(gè),另一個(gè)也會(huì)跟著改變?!禞avascript 高級(jí)程序設(shè)計(jì)》中的圖例其實(shí)很形象
2.參數(shù)傳遞
JavaScript中的參數(shù)傳遞全部是按照值傳遞的?;绢愋妥鰠?shù)一般都不會(huì)有什么困惑,如果引用類型做了參數(shù),類似下面這個(gè)例子:
function setName(obj){ obj.name = "tom"; } var person = new Object(); setName(person); alert(person.name);//顯示tom
這個(gè)例子中我們?cè)趕etName中修改了變量的內(nèi)容,在函數(shù)外也生效了。剛開始我也以為程序執(zhí)行應(yīng)該會(huì)彈出 undefined 或者報(bào)錯(cuò),但是卻彈出了在函數(shù)的作用域中修改的值。分析了一下參數(shù)傳遞的整個(gè)過程,這個(gè)疑惑就解決了。在參數(shù)傳遞的過程中,有很重要的一步:變量值復(fù)制。我們?cè)谡{(diào)用函數(shù)時(shí)其實(shí)進(jìn)行了 obj=person 這樣一步操作,所以根據(jù)上面提到的引用類型變量值復(fù)制的特點(diǎn),當(dāng)我們修改obj時(shí),同時(shí)也就修改了person的值。所以JS參數(shù)傳遞的方式是值傳遞,并且只能是值傳遞。
3.執(zhí)行環(huán)境、變量對(duì)象、作用域鏈
我對(duì)執(zhí)行環(huán)境、執(zhí)行環(huán)境的理解有點(diǎn)類似與類和對(duì)象:
執(zhí)行環(huán)境中定義了變量、函數(shù)和函數(shù)可以訪問到的其他數(shù)據(jù),而當(dāng)這個(gè)執(zhí)行環(huán)境被激活時(shí),就會(huì)根據(jù)這個(gè)執(zhí)行環(huán)境創(chuàng)建出一個(gè)變量對(duì)象提供給解析器使用。執(zhí)行環(huán)境就好比是類,變量對(duì)象就對(duì)應(yīng)是對(duì)象。
當(dāng)一個(gè)執(zhí)行環(huán)境激活時(shí),它就會(huì)被推入一個(gè)棧的棧頂中執(zhí)行,當(dāng)它執(zhí)行完畢,會(huì)將它移出棧,執(zhí)行在它之前進(jìn)入棧的環(huán)境,以此類推。
而作用域鏈相當(dāng)于一個(gè)存放變量對(duì)象的棧,越早被激活的執(zhí)行環(huán)境創(chuàng)建出的變量對(duì)象越在下面,當(dāng)前激活的執(zhí)行環(huán)境的變量對(duì)象位于棧頂。如果當(dāng)前執(zhí)行環(huán)境執(zhí)行完畢,那么就需要將棧頂?shù)淖兞繉?duì)象(對(duì)應(yīng)執(zhí)行環(huán)境)從棧頂移出。
而執(zhí)行環(huán)境在執(zhí)行時(shí),解析器需要訪問變量等數(shù)據(jù)都是從作用域頂端開始查找,也就是從當(dāng)前執(zhí)行環(huán)境對(duì)應(yīng)的變量對(duì)象開始查找,如果查找不到,則往下進(jìn)入外層執(zhí)行環(huán)境對(duì)應(yīng)的變量對(duì)象中查找,一直持續(xù)到找到需要的對(duì)象或找到全局環(huán)境的變量對(duì)象為止。所以這種查找方式也就說(shuō)明了太多定義在全局環(huán)境中的變量比較影響程序的性能。
今天學(xué)習(xí)的東西主要是概念性質(zhì)的,而且比較抽象。但是這部分對(duì)于后面所有的知識(shí)都是基礎(chǔ),像是之后的閉包啊,繼承啊,原型啊都要對(duì)這部分內(nèi)容有很好的理解才能學(xué)的更明白透徹,所以這部分內(nèi)容應(yīng)該反復(fù)學(xué)習(xí),要相信溫故而知新,古人誠(chéng)不欺我也(。・∀・)ノ゙
相關(guān)文章
JS獲取多維數(shù)組中相同鍵的值實(shí)現(xiàn)方法示例
這篇文章主要介紹了JS獲取多維數(shù)組中相同鍵的值實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了JS數(shù)組遍歷、判斷、鍵值獲取等操作技巧,需要的朋友可以參考下2017-01-01BootStrap框架個(gè)人總結(jié)(bootstrap框架、導(dǎo)航條、下拉菜單、輪播廣告carousel、柵格系統(tǒng)布局、標(biāo)簽頁(yè)
這篇文章主要介紹了BootStrap框架個(gè)人總結(jié)(bootstrap框架、導(dǎo)航條、下拉菜單、輪播廣告carousel、柵格系統(tǒng)布局、標(biāo)簽頁(yè)tabs、模態(tài)框、菜單定位)的相關(guān)資料,需要的朋友可以參考下2016-12-12JS實(shí)現(xiàn)把鼠標(biāo)放到鏈接上出現(xiàn)滾動(dòng)文字的方法
這篇文章主要介紹了JS實(shí)現(xiàn)把鼠標(biāo)放到鏈接上出現(xiàn)滾動(dòng)文字的方法,涉及JavaScript響應(yīng)鼠標(biāo)事件動(dòng)態(tài)操作頁(yè)面元素的相關(guān)技巧,需要的朋友可以參考下2016-04-04js實(shí)現(xiàn)左側(cè)網(wǎng)頁(yè)tab滑動(dòng)門效果代碼
這篇文章主要介紹了js實(shí)現(xiàn)左側(cè)網(wǎng)頁(yè)tab滑動(dòng)門效果代碼,涉及JavaScript頁(yè)面元素的遍歷及元素屬性動(dòng)態(tài)切換的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09JavaScript數(shù)據(jù)類型及相互間的轉(zhuǎn)換規(guī)則
這篇文章主要介紹了JavaScript數(shù)據(jù)類型及相互間的轉(zhuǎn)換規(guī)則,文章通過圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09javascript 函數(shù)限制調(diào)用代碼
javascript 函數(shù)限制調(diào)用代碼,需要的朋友可以參考下。2010-05-05