變數類型:基本類型和引用類型 基本類型上節已經提到。基本類型的值是按值傳遞的,既改變形參的值不會影響實參 其中,a(x)為100 ,alert(x)為1 可見js的基本類型是按值傳遞的 引用類型:由多個值構成的對象,是按照共用傳遞的,也就是對象屬性的形參的改變會影響對象屬型的改變,對象形參的改變不會 ...
變數類型:基本類型和引用類型
基本類型上節已經提到。基本類型的值是按值傳遞的,既改變形參的值不會影響實參
<html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script> var x=1; function a(o){ o=100; alert(o); } a(x); alert(x); </script> </body> </html>
其中,a(x)為100 ,alert(x)為1 可見js的基本類型是按值傳遞的
引用類型:由多個值構成的對象,是按照共用傳遞的,也就是對象屬性的形參的改變會影響對象屬型的改變,對象形參的改變不會影響對象的改變。
<html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script> var obj={x:1}; function a(){ arguments[0].x=2; } a(obj); alert(obj.x); </script> </body> </html>
可見alert(obj.x)為2 由此知對象屬性的形參的改變會使對象的屬性改變
<html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script> var obj={x:1}; function a(){ arguments[0]=2; } a(obj); alert(obj.x); </script> </body> </html>
alert(obj.x)為1 可見對象的形參的改變不會影響對象
還有一點要註意的是,JavaScript有聲明提前的特性,也就是說你可以先調用一個變數,然後聲明,但是變數的賦值是不會提前的。
<html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script> alert( a); var a=1; </script> </body> </html>
此時alert返回的結果是undefined ,可見a確實聲明瞭
在變數的複製過程中,按值傳遞與按共用傳遞也是不同,對於按值傳遞 在string基本類型中,每一次對字元串的修改操作,實際都是新建了一個變數。
var a=1; var b=a;
其過程是a,b是完全獨立的,這兩個值參與的任何操作不會互相影響
按共用傳遞
var obj1={x:1}; var obj2=obj1; obj2.x=2; alert(obj1.x);
此時,alert輸出的值也為2,可見屬性的改變時會相互影響的,但對象之間互不影響。
instancof操作符 用於檢查對象的類型,如Array,RegExp 用法實例:alert(colors instanceof Array); 其返回值為boolean
作用域
(執行)環境:js的最重要的概念。每個執行環境都有一個關聯的變數對象,改環境中的變數和函數都保存在這個變數對象中,解釋器在後臺會使用它。
全局執行環境的變數對象是window,那麼這個window對象就保存著全局變數和函數。
每一個函數都有一個執行環境,可以理解為局部環境,但執行流到達函數時,環境會置於一個環境棧中,當執行完畢後,環境棧會把這個函數環境彈出,繼續執行下一個環境。
當一個環境遇到執行流時,會創建變數對象的一個作用域鏈,改作用域鏈的前端為當前的變數對象,如這個環境是函數,那麼這個變數對象又稱為活動對象,這個對象做開始只包含一個arguments變數。作用域鏈的下一個變數對象是包含環境,在下一個亦是上一個的包含環境,所以,作用域鏈的末尾的變數對象永遠都是window(全局執行環境的變數對象),那麼,內部環境可以通過作用域鏈訪問外部環境,外部環境則不能。
也就是說,var聲明的變數會被自動添加到離他最近的環境中(向上),在函數內部,就是該函數的環境,在with中,也是相應的環境。
那麼,可以通過with或者try--catch來演唱作用域鏈,即在作用域鏈的前端增加一個變數對象。如下
function a(){ var a=true; with(location){ var url=href+a; } return url; } a();
需要註意一點,js沒有塊級作用域
變數查詢(查詢標識符)當某個環境為了讀取或者引用一個標識符時,就要進行檢索過程,搜索過程從作用域鏈的前端開始,向上逐級查詢,遇到匹配的就停止。
垃圾收集:js具有自動清除垃圾的能力,切這個功能是迴圈進行的(時間間隔),垃圾清理主要是為了減少記憶體的浪費,對不再使用的變數進行銷毀,釋放記憶體。
1.標記清除法:js既然要自動清除垃圾,那麼就要知道哪些是需要清理的,哪些是需要保留的,最簡單的方法便是mark,當執行流執行到一個變數時,這個變數會被標記為“進入環境”,當執行結束後,便會被標記“離開環境”,當然標記的方法是多種多樣的,可以是位翻轉或者列表,這也是標記清除的思想。在標記清除中,垃圾收集器在運行時會對所有記憶體中的變數都加上標記,然後,他會去掉環境中的變數以及被環境中的變數引用的變數的標記,在此之後,在為這些變數添加標記,這些變數將被視為要刪除的變數,最後完成記憶體清除操作。
2.引用計數:跟蹤記錄每個值得引用次數,每被變數引用一次,就加1,若變數去了其他的值,就-1,直到為0,進行清除。這回倒著一個迴圈引用問題的出現,導致記憶體的浪費。