原文地址:https://www.cnblogs.com/phermis/p/7307209.html
今天看到大神寫得一片文章,自己對全局變量和局部變量的理解還是不夠深刻,因此寫到這篇文章,做個總結。
大神代碼截圖+理解文字如下:

解析:上面代碼中,變量i是var命令聲明的,在全局范圍內都有效,所以全局只有一個變量i。每一次循環,變量i的值都會發生改變,而循環內被賦給數組a的函數內部的console.log(i),里面的i指向的就是全局的i。也就是說,所有數組a的成員里面的i,指向的都是同一個i,導致運行時輸出的是最后一輪的i的值,也就是10。
一、定義
局部變量:變量在函數內聲明,只能在函數內部訪問。
全局變量:變量在函數外定義,整個代碼都可以調用的變量。
聲明關鍵字:var。 JavaScript中可以隱士的使用變量,不用聲明變量直接使用。JavaScript中把隱士聲明的變量總是當成全局變量來使用的。
二、變量提升(這個知識點如果不了解,那么就容易坑)
由於JS引擎的工作方式,是先獲取所有被聲明的變量在逐一執行,所以變量的聲明語句都會被提升到當前代碼塊的頭部。
注:代碼塊/方法塊===>指的是Function的一對大括號{ }, 切忌,是Function塊,而for、while、if、塊並不是作用域的划分標准。
三、進一步了解

代碼提升的效果所以實際執行的代碼是這樣的:
<script type="text/javascript">
var a = 1;
function test1() {
var a; //i未賦值【當局部變量與全局變量重名時,局部變量優先級高於全局變量,所以會覆蓋全局變量,此時的a只有聲明卻未定義】
alert(a);//所以執行alert值為undefined
a = 2;
alert(a);
}
test1();
alert(a);//undefined 2
</script>
四、例子
JavaScript的變量的scope是根據方法塊來划分的(也就是說Function的一對大括號{ }來划分)。在這里再次強調一遍:是Function塊,而for、while、if 塊並不是作用域的划分標准。其變量不會被提升。
js中作用域只有函數作用域和全局作用域,當不在函數里那就是全局作用域了。【參考地址:http://www.cnblogs.com/zhus/p/6513741.html】
<script type="text/javascript">
function test2() {
alert("before for scope:" + i); //i未賦值【並不是未聲明!使用未聲明的變量或函數全拋出致命錯誤而中斷腳本執行】
for (var i = 0; i < 3; i++) {
alert("in for scope:" + i); // i的值是 0、1、2, 當i為3時跳出循環
}
alert("after for scope:" + i); // i的值是3,注意,此時已經在for scope以外,但i的值仍然保留為3
while (true) {
var j = 1;
break;
}
alert(j); // j的值是1,注意,此時已經在while scope以外,但j的值仍然保留為1
if (true) {
var k = 1;
}
alert(k); //k的值是1,注意,此時已經在if scope以外,但k的值仍然保留為1
}
test2();
//若在此時(function scope之外)再輸出只存在於test2 這個function scope里的 i、j、k變量會發生神馬效果呢?
alert(i); //error! 沒錯,是error,原因是變量i未聲明(並不是未賦值,區分test2函數的第一行輸出),導致腳本錯誤,程序到此結束!
alert("這行打印還會輸出嗎?"); //未執行
alert(j); //未執行
alert(k); //未執行
</script>
參考資料:http://blog.csdn.net/zyz511919766/article/details/7276089

