JavaScript作用域詳解

大額_skylar的部落格發表於2014-09-23

黃金守則第一條:

js沒有塊級作用域(你可以自己閉包或其他方法實現),只有函式級作用域,函式外面的變數函式裡面可以找到,函式裡面的變數外面找不到。

first try:

這是為什麼呢??

 1 var a = 10;
 2         function aaa(){//step-4
 3             alert(a);//step-5->執行alert,此時只能找到外面的a=10故彈框10
 4         }
 5         function bbb(){//step-2
 6             var a = 20;
 7             aaa();//step-3
 8         }
 9         //定義了函式沒啥用,呼叫才是真格的所以這裡是step-1
10         bbb();//step-1

其實原理大家都懂,應該就是易錯而已,萬變不離其綜。

second try:

這是為什麼呢? 因為給a賦值b的時候,b還沒有定義,所以a是undefined,b是10.

黃金守則第二條:

變數的查詢是就近原則,去尋找var定義的變數,當就近沒有找到的時候就去查詢外層。

look:

這是為什麼呢、? 這裡面有兩個原因,一是預解析,二是就近查詢。

 1         var a=10;
 2         function aaa(){
 3             alert(a);//undefined,查詢a的時候會現在函式內查詢,由於預解析的作用,此時的a是undefined,因此永遠不會去查詢外面的10了
 4             var a = 20;
 5 
 6             /*預解析
 7             var a
 8             alert(a);
 9             var a = 20;*/
10 
11         }
12         aaa();

attention:

這個吧,就驗證了第二條,雖然是就近原則,但是是就近找var宣告的變數,這個是因為沒有var宣告的變數是全域性的,這裡只是修改了a的值。所以上面就是因為在函式內沒找到var的a,於是到外面去找了,一找就找到了,於是a就alert出10了;不過沒錯的是a=20後,a確實為20了,只不過alert的時候還沒有執行到那~~

看吧~

下面這個例子,更加驗證了js的函式作用域 而已:

這是因為在alert(a)的時候,bbb函式中的a確實為20 ,可是它對於這時的alert(a)這句話來說是區域性的,alert(a)根本找不到bbb函式中的a,所以在aaa函式中它找不到a,於是乎去外面找,一找,就找到了10。

黃金守則第三條:

當引數跟區域性變數重名時,優先順序是等同的。

例:

還有:傳參時,基本型別傳值,引用型別傳引用。(但是重新賦值之後就不是這樣了喔)

1         var a = 5;
2         var b = a;
3         b +=3;
4         alert(a);//5
5 
6         var a = [1,2,3];
7         var b=a;
8         b.push(4);
9         alert(a);//[1,2,3,4];

上面程式碼沒有問題,但是下面就不一樣啦。

因為b被重新賦值了,不指向a了。

此外,引數與變數的作用域是相似的:

對比上下這兩個:

上面是引數是基本型別,只傳了值進去,下面的傳個引用型別:(同樣也包含重新賦值的情況)

相關文章