《變量、作用域和內存問題》
一、
1、JavaScript變量可能包含兩種不同類型的值:基本類型值和引用類型值。基本類型值指的是簡單的數據段,而引用類型值指那些可能由多個值構成的對象。
5種基本數據類型是按值訪問的,因爲可以操作保存在變量中的實際值。
引用類型的值是保存在內存中的對象。與其他語言不同,JavaScript不允許訪問內存中的位置,也就是說不能直接操作對象的內存空間。在操作對象時,實際上是在操作對象的引用而不是實際的對象。爲此,引用類型的值是按引用訪問的。
2、只能給引用類型值動態添加屬性。
3、賦值變量值:基本數據類型值和副本是完全獨立的;
引用類型複製的值(副本)其實是一個指針,兩個變量實際上引用同一個對象(儲存在堆中的某個對象)。
4、所有函數的參數都是按值傳遞的,在傳遞引用類型的值時,會把這個值(全局對象)在內存中的地址賦值給一個局部變量,局部變量(函數參數)的變化會反映在函數外部。而且,即使在函數內部修改了參數的值,單原始的值傳遞的對全局對象的引用沒有改變(也證明了函數參數是值傳遞而非引用傳遞)
eg:
/*引用數據類型的函數參數傳遞*/
function setName(obj){
obj.name="summer";
obj=new Object();
obj.name="rose";
}
var person=new Object();
setName(person);
alert(person.name);
警示框結果爲:summer
5、在檢測引用類型的值時(根據原型鏈可識別),(想知道它是什麼類型的對象),用instanceof操作符,如果變量是給定引用類型的實例則返回ture;(ps:所有引用類型的值都是Object的實例,都返回ture)
6、使用tepyof檢測函數時,safari 5級以前和Chorome 7及以前返回“function”;對正則表達式也返回”fuction“;
IE、FF對正則表達式返回“object”。
二、
1、執行環境定義了變量或函數有權訪問的其他數據,決定了他們各自的行爲。每個執行環境都以一個與之關聯的變量對象(後臺使用)
2、每個函數都有自己的執行環境(環境棧機制)。
3、當代嗎在一個環境中執行時,會創建變量對象的一個作用域鏈,保證對執行環境有權訪問的所有變量和函數的有序訪問。
作用域鏈前端(當前執行代碼所在環境的變量對象,比如函數環境裏的活動對象)
作用域鏈的最後一個對象:全局執行環境的變量對象
4、在局部作用域中定義的變量對象可以在局部環境與全局變量互換使用。
5、內部環境可以通過作用域鏈訪問所有外部環境,反之不行。這些環境之間的聯繫是線性的、有序的。
6、執行環境的類型兩種:全局和局部環境(函數)
但可以在一下兩種情況延長作用域鏈:前端臨時增加,代碼執行後移除
A:try catch 的catch 語塊(IE8以後創建的是catch中的變量對象)
B:with(~)
/*延長作用域鏈*/
function buildUrl() {
var qs = "sdkjhds";
with (location)
{
var url = href + qs;
}
console.log(url);
}
buildUrl();
7、沒有塊級作用域(和C不同之處)
比如if語句、for語句,執行結束後,依舊存在與外部執行環境中(相近的)
使用var申明的變量會自動被添加到最近的執行環境中;在with語句中,最接近的環境是函數環境;沒有使用var申明,則添加到全局環境。
8、初始化變量之前,一定要先申明最好,嚴格模式下,初始化未經申明的變量會導致錯誤。
9、如果局部環境中存在同名標識符,就不會使用父環境中的標識符。
三
1、自動垃圾收集機制:
標記清除:主流
引用清除:在IE中訪問非原生javascript對象 以及代碼中存在循環引用現象會導致問題
2、解除變量:通過將其值設置爲null (不再使用的全局對象、全局變量以及循環引用變量的引用)
本章知識總結已完成!