Javascript面向對象編程指南(三)

變量的作用域

這是一個至關重要的為題。特別是當我們從別的語言轉向JS的時,必須要明白這一點,即在Javascript中,變量的定義并不是以代碼塊作為作用域的,而是以函數作為作用域的。也就是說,如果變量是在某個函數中定義的,那么它在函數以外的地方是不可見的。而如果變量是定義在if或者for這樣的代碼塊中的,它在代碼塊以外是可見的。另外,在Javascript中,術語“全局變量”指的是定義在所有函數之外的變量(也就是定義在全局代碼中的變量),與之相對的是“局部變量”,所指的則是在某個函數中定義的變量。其中,函數內的代碼可以像訪問自己的局部變量那樣訪問全局變量,反之,則不行。

下面來看一個具體演示,請注意兩點:

  • 函數f()可以訪問變量global;
  • 在函數f()以外,變量local是不存在的。
var global = 1;
function f() {
  var local = 2;
  global ++;
  return global;
}

f();  // 2
f();  // 3
local;  // local is not defined

這里還有一點很重要,如果我們聲明一個變量時沒有使用var語句,該變量就會被默認為全局變量。

最佳實踐

  • 盡量將全局變量的數量降到最低,以避免命名沖突,因為如果有兩個人在同一腳本的不同函數中使用了相同的全局變量名,就很容易到很容易導致不可預測的結果喝難以觀察的bug
  • 最好總是使用var語句來聲明變量
  • 可以考慮使用“單一var”模式,即,僅在函數體內的第一行使用一個var來定義這個作用域中所有需要的變量。這樣一來,我們就能很輕松地找到相關變量的定義,并且在很大程度上避免了不小心污染全局變量的情況。
變量提升

下面我們來看一個很有趣的例子,它顯示了關于局部和全局作用域的另一個重要問題。

var a = 123;
function f(){
  alert(a);
  var a = 1;
  alert(a);
};
f();

你可能會想當然的認為alert()第一次顯示的是123(也就是全局變量a的值),而第二次顯示的是1(即局部變量a)。但事實上并非如此,第一個alert()實際上顯示的是undefined,這是應為函數域始終優(yōu)先于全局域,所以局部變量a會覆蓋掉所有與它同名的全局變量,盡管在alert()第一次被調用時,a還沒有被正式定義(即該值為undefined),但該變量本身已經存在于本地空間了。這種特殊的現象叫做提升。

也就是說,當Javascript的執(zhí)行過程進入新的函數時,這個函數內被聲明的變量都會被移動(或者說被提升)到函數最開始的地方。這個概念很重要,必須牢記。另外需要注意的是,被提升的只有變量的聲明,這意味著,只有函數體內聲明的這些變量在該函數執(zhí)行開始時就存在,而與之相關的賦值操作并不會被提升,它還在原來的位置上。譬如在上面的例子中,局部變量本身被提升到了函數開始處,但并沒有在開始處就被賦值為1。這個例子可以等價為:

var a = 123;
function f() {
  var a;
  alert(a);  // undefined
  var a =1;
  alert(a)  // 1
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 第一章: JS簡介 從當初簡單的語言,變成了現在能夠處理復雜計算和交互,擁有閉包、匿名函數, 甚至元編程等...
    LaBaby_閱讀 1,756評論 0 6
  • 來源:仗劍走天涯! 關于javascript的作用域的一些總結,主要參考以上文章,加上自己的整理的理解。 近日對j...
    Michael_林閱讀 1,020評論 0 1
  • 深入理解JavaScript系列文章,包括了原創(chuàng),翻譯,轉載,整理等各類型文章,如果對你有用,請推薦支持一把,給大...
    DaveWeiYong閱讀 694評論 0 1
  • 透過六月的蔥蘢新翠, 看枝頭灑落日光暈圈。 綠肥紅瘦, 燕舞鶯歌, 掬一捧清泉, 聞晶瑩滴過荷葉尖尖。 稚女的白裳...
    知識管理某李閱讀 214評論 1 4

友情鏈接更多精彩內容