萬盛學電腦網

 萬盛學電腦網 >> 腳本專題 >> javascript >> js變量、作用域及內存詳解

js變量、作用域及內存詳解

 基本類型值有:undefined,NUll,Boolean,Number和String,這些類型分別在內存中占有固定的大小空間,他們的值保存在棧空間,我們通過按值來訪問的。

(1)值類型:數值、布爾值、null、undefined。
(2)引用類型:對象、數組、函數。

如果賦值的是引用類型的值,則必須在堆內存中為這個值分配空間。由於這種值的大小不固定(對象有很多屬性和方法),因此不能把他們保存到棧內存中。但內存地址大小是固定的,因此可以將內存地址保存在棧內存中。

1 2 3 4 5 6 <script type="text/javascript”> var box = new Object(); //創建一個引用類型 var box = "lee";  //基本類型值是字符串 box.age = 23;  //基本類型值添加屬性很怪異,因為只有對象才可以添加屬性。 alert(box.age); //不是引用類型,無法輸出; </script>

簡而言之,堆內存存放引用值,棧內存存放固定類型值。

js變量、作用域及內存詳解 三聯

1 2 3 4 5 6 7 8 <script type="text/javascript">   var man = new Object();//man指向了棧內存的空間地址   man.name = "Jack";   var man2 = man;//man2獲得了man的指向地址      alert(man2.name);//兩個都彈出Jack   alert(man.name); </script>

復制變量值

再看下面這個例子:

1 2 3 4 5 6 7 8 9 <script type="text/javascript">   var man = new Object();//man指向了棧內存的空間地址   man.name = "Jack";   var man2 = man;//man2獲得了man的指向地址      man2.name = "ming";//因為他們都指向同一個object,同一個name,不管修改誰,大家都修改了   alert(man2.name);//兩個都彈出ming   alert(man.name); </script>

由以上可以得出:在變量復制方面,基本類型和引用類型也有所不同,基本類型復制的是值本身,而引用類型復制的是地址。

傳遞參數

ECMAScript中,所有函數的參數都是按值傳遞的,

1 2 3 4 5 6 7 8 9 10 11 <script type="text/javascript">    function box(num){   //按值傳遞      num+=10;      return num;    }       var num = 10;    var result = box(num);    alert(result); //如果是按引用傳遞,那麼函數裡的num會成為類似全局變量,把外面的number替換掉    alert(num);  //也就是說,最後應該輸出20(這裡輸出10) </script>

javascript沒有按引用傳遞的,如果存在引用傳遞的話,那麼函數內的變量將是全局變量,在外部也可以訪問。但這明顯是不可能的。

執行環境及作用域

執行環境是javascript中最為重要的概念之一,執行環境定義了變量或函數有權訪問其他數據。

全局執行環境是最外圍的執行環境,在web浏覽器中,全局執行環境是window對象,因此,所有的全局變量的函數都是作為window的屬性和方法創建的。

1 2 3 4 5 6 7 8 9 <script type="text/javascript">    var name = "Jack";      //定義全局變量    function setName(){      return "trigkit4";    }       alert(window.name);    //全局變量,最外圍,屬於window屬性    alert(window.setName()); //全局函數,最外圍,屬於window方法 </script>

當執行環境內的代碼執行完畢後,該環境被銷毀,保存其中的變量和函數也隨之銷毀,如果是全局環境,需所有程序執行完畢或網頁完畢後才會銷毀。

去掉var的局部變量

1 2 3 4 5 6 7 8 9 <script type="text/javascript">    var name = "Jack";    function setName(){      name = "trigkit4";  //去掉var變成了全局變量    }       setName();    alert(name);//彈出trigkit4 </script>

通過傳參,也是局部變量

1 2 3 4 5 6 7 8 9 <script type="text/javascript">    var name = "Jack";    function setName(name){  //通過傳參,也是局部變量      alert(name);    }       setName("trigkit4");//彈出trigkit4    alert(name);//彈出Jack </script>

函數體內還包含函數,只有這個函數才可以訪問內一層的函數

1 2 3 4 5 6 7 8 9 <script type="text/javascript">    var name = "Jack";    function setName(){      function setYear(){  //setYear()方法的作用域在setName()內        return 21;      }    }    alert(setYear());//無法訪問,出錯  </script>

可以通過如下方法進行訪問:

1 2 3 4 5 6 7 8 9 10 <script type="text/javascript">    
copyright © 萬盛學電腦網 all rights reserved