1、在js中,變量的定義並不是以代碼塊做爲做用域的,而是以函數做爲做用域。也就是說,若是變量是在某個函數中定義的,那麼,它在函數之外的地方是不可見的。可是,若是該變量是定義在if或者for這樣的代碼塊中,它在代碼塊以外是可見的。函數
2、在js中,術語「全局變量」指的是定義在全部函數以外的變量(也就是定義在全局代碼中的變量),與之相對的是「局部變量」,所指的是在某個函數中定義的變量。其中,函數內的代碼能夠像訪問本身的局部變量那樣訪問全局變量,反之則不行。測試
3、下面是具體示例,請注意兩點:3d
1> 函數f()能夠訪問變量global。blog
2> 在函數f()之外,變量local是不存在的。作用域
var global = 1;
function f() {
var local = 2;
global ++;
return global;
}
測試結果以下:io
還有一點要注意:若是咱們聲明一個變量事沒有使用var語句,該變量就會被默認爲全局變量。讓咱們來看一個示例:function
function f () {
local = 2;
}
undefined
local;
VM432:1 Uncaught ReferenceError: local is not defined
f();
undefined
local;
2變量
圖:im
咱們來看上面代碼發生了什麼:首先,咱們在函數f()中定義了一個變量local。在該函數被調用以前,這個變量並不存在。該變量會在函數首次被調用時建立,並被賦予全局做用域。這使得咱們能夠在該函數之外的地方訪問它。命名
4、最佳實踐:
1>儘可能將全局變量的數量降到最低,以免命名衝突。
2>最好老是使用var語句來聲明變量。
3>能夠考慮使用「單一var」模式,即,僅在函數體內的第一行使用一個var來定義這個做用域中全部須要的變量。這樣一來,咱們就能很輕鬆地找到相關變量的定義,而且在很大程度上避免了不當心污染全局變量的狀況。
5、變量提高
舉例:
var a = 123;
function f(){
alert(a);
var a = 1;
alert(a);
}
f();
圖:
你可能會想固然的認爲alert()第一次顯示的是123(即全局變量a的值),而第二次顯示的是1(即局部變量a)。但事實並不是如此,第一個alert()實際上顯示的是undefined,這是由於函數域始終優先於全局域,因此全局變量a會覆蓋掉全部與它同名的全局變量,儘管在alert()第一次被調用時,a尚未被證明定義(即,該值是undefined),但該變量自己已經存在於本地空間了。這種特殊的現象叫作提高。
結果如圖:
也就是說,當js執行過程進入新的函數時,這個函數內被聲明的全部變量全部變量都會被移動(或者說提高)到函數最開始的地方。另外,須要注意,被提高的只有變量的聲明,這意味着,只有函數體內聲明的這些變量在該函數執行開始時就存在,而與之相關的賦值操做並不會被提高,它還在原來的位置上。譬如,在原來的例子中,局部變量自己被提到了函數開始處,但並無在開始處就被賦值爲1。這個例子能夠被等價地改寫爲:
固然,咱們能夠採用最佳實踐中提到過的單一var模式。在這個例子中,咱們能夠手動提高變量聲明的位置,這樣一來代碼就不會被js的提高行爲所混淆了。