部門技術交流中學習了這篇文章:javascript
的確是一篇很不錯的文章。回來再琢磨了一下,以爲有兩點是要重點注意的:java
1. javascript中沒有block級做用域,但有函數級做用域函數
2. JS引擎執行函數的時候,會首先根據函數體內的變量聲明(注意不是定義)分配變量的內存資源,無論這些變量聲明的位置。而當遇到和函數做用域外名稱相同的變量,中函數內部會覆蓋掉函數做用域外的變量學習
對於第一點,引用原文的示例代碼作一點點改動:spa
<script type="text/javascript"> function rainman(){ // rainman函數體內存在三個局部變量 i j k var i = 0; if ( 1 ) { var j = 0; for(var k = 0; k < 3; k++) { alert( k ); //分別彈出 0 1 2 } alert( k ); //彈出3 } alert( j ); //彈出0 } rainman(); alert(i); </script>
rainman中的i,j,k能夠正常輸出,由於它們都在函數rainman中定義的,在函數內都是可用的。
但最後一個alert(i)則會出現腳本運行錯誤!由於超出了rainman的做用域,i變得不可用!因此說JS是有函數級做用域,但沒有block級做用域!code
有意思的是第二點。htm
再一次,引用原文的代碼:blog
<script type="text/javascript"> var x = 1; function rain(){ alert( x ); //彈出 'undefined',而不是1 var x = 'rain-man'; alert( x ); //彈出 'rain-man' } rain(); </script>
爲什麼第一個alert彈出的是undefined???
個人理解是,JS引擎執行函數的時候,會首先根據函數體內的變量聲明(注意不是定義!)分配了函數體內所用的變量內存資源,無論這些變量聲明的位置是在開頭仍是結束!ip
由這個例子進一步,若是var x='rain-man'是有條件的去執行的,JS引擎還會不管如何都先給x分配資源嗎??看代碼:
<script type="text/javascript"> var x = 1; function rain(){ alert( x ); //彈出 'undefined',而不是1 if(0) var x = 'rain-man'; alert( x ); //彈出 'undefined' } rain(); </script>
答案是確定的。即便分支不會走到,JS引擎仍是不管如何都給x先分配了內存!而一如既往的是,函數內部的x會在函數內部的做用域中覆蓋掉外部的x。