標籤:使用 關係 迴圈 複製 垃圾 自動 全域變數 記憶體 處理
一,JavaScript中的變數
1,JavaScript變數是鬆散類型的,決定了它的本質就是:在特定的生命週期中,儲存特定的值。因為不存在定義某個變數必須要儲存何種資料類型,因此其值和資料類型是可以在生命週期內改變。,
2,JavaScript變數有兩種資料類型的值:基本類型值和參考型別值。參考型別值是用多個值構成的對象。
在將一個值賦值給一個變數時,解析器必須先確定這個是基礎資料型別 (Elementary Data Type)還好參考型別值。
其中5中基礎資料型別 (Elementary Data Type)是按值訪問的,因為可以操作儲存在變數中的實際的值;參考型別的值儲存的是記憶體中的對象,(也就是說不能直接改變對象中的具體指,必須先訪問該變數訪問到對象地址。參考型別的值是按引用訪問的。)
3,屬性的可變現:基礎資料型別 (Elementary Data Type),可以改變值;引用資料類型,可以對屬性增刪改查,
4,複製變數值:(賦值給另一個變數)
按值傳遞是做了一個副本,在副本上操作和原來的變數沒有關係;按引用傳遞是指向同一個檔案,比如obj1複製給obj2,則obj1和obj2,改變檔案,都會影響彼此的值。
。。。。。。。。
5,變數作為傳遞參數(無論是基礎資料型別 (Elementary Data Type)還是引用資料類型,都是按照值傳遞!!!!)
基礎資料型別 (Elementary Data Type)按值傳遞沒什麼疑問,但是參考型別呢?說參考型別按值傳遞,更準確的說是參考型別是將全域參考型別的地址按值傳遞。然後按照參考型別切斷指向的規則,處理!!!!!!!!!!
(如果在函數體內建立對象,指向外部的參考型別,操作新對象並不會影響外部參考類型)
function setName(obj){obj.name="lipengffei"} var person=new Object(); setName(person);alert(person.name);//"lipengfei"
//在這裡並沒有在函數體內建立新的對象,而是按值傳遞建立了一個obj,指向person 。利用該地址聲明並賦值了一個屬性。這樣再利用person訪問,就同樣會訪問到了,而結束後,obj就消失了。但是person中的內容卻儲存了下來。
function setName(obj){ obj.name="sdfsd";obj=new object();obj.name="abc";} var person=new Object();setName(person);alert(person.name);//sdfsd;
//在這裡函數體中又聲明了一次obj,這樣就切斷了原來obj的指向。這樣就和person沒有關係了。以後的操作就是各自操作各自的了、
6,檢查類型
要檢查一個變數是不是基礎資料型別 (Elementary Data Type),用的是typeof
如果是基礎資料型別 (Elementary Data Type),則返回基礎資料型別 (Elementary Data Type)的類型,如果是null或者對象,則都是返回Object(這樣就不能區分是什麼類型的對象了)
instanceof操作符,則對對象來判斷是否屬於某種參考型別,返回的是true或者false;例如:alert(person instaceof Array);判斷是否是個數組對象。
二,執行環境和範圍
1, 執行環境,定義了變數或者函數有權利訪問其他資料的權利。
在web瀏覽器中,全域環境被認為是window對象,因此所有的全域變數和函數都是作為window的屬性和方法。
在某個環境中執行完,其變數和函數自動銷毀。
2,範圍鏈。
保證對執行環境有權訪問的變數和函數進行有序的訪問。執行順序是從範圍前端,依次往上尋找。例如:一個函數會,先在函數體中作用,影響了外部的某變數,則變數再往上尋找,來作用。
3,延長範圍鏈
在範圍鏈前端臨時增加一個變數對象,該變數對象會在代碼執行完後移除,有兩種情況會是這樣的:
try-catch語句的catch語句塊(會建立一個新的變數對象,包含的是被拋出的錯誤對象的聲明);with語句(將變數添加到指定的範圍中,如url和location.url);
4,沒有塊級範圍
既是在{}中的局部變數在C語言或者java語言中,在外部是不能訪問的到的,而在JavaScript還是會訪問到。這裡說 的{}是指語句的{},而不是函數的局部變數。函數中的局部變數還是不會釋放到外部
這個的原因主要是因為在語句的{}中並沒有封閉的執行環境,他們還是在同一個執行環境中,因此會訪問到。而其他語言是不能的!!!!!
三,垃圾清除
JavaScript的記憶體回收是自動回收機制,離開範圍的變數值將被自動標籤,自動清除。
“標記清除”是目前最主流的記憶體回收機制,思想是給當前不使用的值上加上標記,然後回收。
“引用計數”思想是記錄所有值被引用的次數,這種演算法是有問題的!!!!!例如循環參考。
解除一個對象的佔用空間直接用null就可以了。
JavaScript的變數,範圍和記憶體問題