變量,作用域和內(nèi)存問題

基本類型和引用類型的值

變量可能包含兩種不同數(shù)據(jù)類型的值:基礎(chǔ)類型值和引用類型值。
基本類型是按值訪問的,因?yàn)榭梢圆僮鞅4嬖谧兞恐械膶?shí)際值。引用類型的值是保存在內(nèi)存中的對象。JavaScript不允許直接訪問內(nèi)存中的位置,不能直接操作對象的內(nèi)存空間。引用類型的值是按引用訪問的。

動態(tài)的屬性

對于引用類型的值,我們可以為其添加屬性和方法,也可以改變和刪除其屬性和方法。
var person = new object();
person.name = “chenjiaxing”;
alert(person.name); //“chenjiaxing”
以上代碼創(chuàng)建了一個(gè)對象并將其保存在了變量person中。如果對象不被銷毀或者這個(gè)屬性不被刪除,則這個(gè)屬性將一直存在。但是,我們不能給基本類型的值添加屬性。
var name =“chenjiaxing”;
name.age = 27;
alert(name.age); //undefined
說明只能給引用類型值動態(tài)地添加屬性。

復(fù)制變量值

如果從一個(gè)變量向另一個(gè)變量復(fù)制基本類型值,會在變量對象上創(chuàng)建一個(gè)新值,然后把該值復(fù)制到為新變量分配的位置上。
var num1=5;
var num2=num1;
在此,num1中保存的是5.當(dāng)使用num1的值來初始化num2時(shí),num2中也保存了值5.但num2和num1中的5是完全獨(dú)立的,該值只是num1中5的一個(gè)副本。

當(dāng)從一個(gè)變量向另一個(gè)變量復(fù)制引用類型的值時(shí),同樣也會存儲在變量對象中的值復(fù)制一份放到為新變量分配的空間中。不同的是,這個(gè)值的副本實(shí)際上是一個(gè)指針,而這個(gè)指針指向存儲在堆中的一個(gè)對象。復(fù)制操作結(jié)束后,兩個(gè)變量實(shí)際上將引用同一個(gè)對象。因此,改變其中一個(gè)變量,就會影響另一個(gè)變量。

傳遞參數(shù)

所有函數(shù)的參數(shù)都是按值傳遞的。
使用數(shù)值等基本類型來說明按值傳遞參數(shù)比較簡單。使用對象:
function setName(obj){
obj.name=“chenjiaxing”;
}
var person = new Object();
setName(person);
alert(person.name); //“chenjiaxing”
在這個(gè)函數(shù)內(nèi)部,obj和person引用的是同一個(gè)對象。

執(zhí)行環(huán)境及作用域

執(zhí)行環(huán)境定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù),決定了它們各自的行為。每個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的變量對象,環(huán)境中定義的所有變量和函數(shù)都保存在這個(gè)對象中。雖然我們編寫的代碼無法訪問這個(gè)對象,但解析器在處理數(shù)據(jù)時(shí)會在后臺使用它。
全局執(zhí)行環(huán)境是最外圍的一個(gè)執(zhí)行環(huán)境。在Web瀏覽器中,全局執(zhí)行環(huán)境被認(rèn)為是windows對象。
每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境。當(dāng)執(zhí)行流進(jìn)入一個(gè)函數(shù)時(shí),函數(shù)的環(huán)境就會被推入一個(gè)環(huán)境棧中。而在函數(shù)執(zhí)行之后,棧將其環(huán)境彈出,把控制權(quán)返回給之前的執(zhí)行環(huán)境。
當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行時(shí),回創(chuàng)建變量對象的一個(gè)作用域鏈。用途是保證對執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問。作用域鏈前端始終都是當(dāng)前執(zhí)行的代碼所在環(huán)境的變量對象。如果這個(gè)環(huán)境是函數(shù),則將其活動對象作為變量對象。

延長作用域鏈

with語句和try-catch語句的catch塊能夠在作用域鏈的前端添加一個(gè)變量對象。對with語句來說,會將指定的對象添加到作用域鏈中。對catch語句來說,會創(chuàng)建一個(gè)新的變量對象。

沒有塊級作用域

JavaScript沒有塊級作用域。
使用var聲明的變量會自動被添加到最接近的環(huán)境中。如果省略了var在外部也能訪問到。
當(dāng)在某個(gè)環(huán)境中為了讀取或?qū)懭攵靡粋€(gè)標(biāo)識符時(shí),必須通過搜索來確定該標(biāo)識符實(shí)際代表什么。

垃圾收集

JavaScript具有自動垃圾收集機(jī)制,也就是說,執(zhí)行環(huán)境會負(fù)責(zé)管理代碼執(zhí)行過程中使用的內(nèi)存。

標(biāo)記清除

可以使用任何方式來標(biāo)記變量。比如,可以通過翻轉(zhuǎn)某個(gè)特殊的位來記錄一個(gè)變量何時(shí)進(jìn)入環(huán)境,或者使用一個(gè)進(jìn)入環(huán)境的變量列表及一個(gè)離開環(huán)境的變量列表來跟蹤哪個(gè)變量發(fā)生了變化。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容