首頁 > web前端 > js教程 > 主體

JavaScript中的變數作用域介紹_javascript技巧

WBOY
發布: 2016-05-16 16:22:57
原創
1353 人瀏覽過

對於變數的作用域(scope),C、Java等語言採取的是「block scope」的方式。與之不同,JavaScript所採取的是「function scope」的方式 — 變數的作用域僅由所處的function決定,與if、for等邏輯塊無關。例如,以下這個例子展示了JavaScript中與C、Java等語言不一樣的行為:

複製程式碼 程式碼如下:

function(){
  var s = 42;//s is visible throughout function
  if (s > 3) {
    var x = "test";//x is visible throughout function
    for(var i=0; i       console.log(i);
    }
    console.log(i);//i is visible throughout function
  }
  console.log(i);
  console.log(x);
}

在C、Java等「block scope」的語言中,if語句、for語句等邏輯區塊結束後,在這些邏輯區塊內部定義的變數將會被銷毀。 JavaScript與之不同,只要一個變數定義在某function內,那麼整個function內的所有程式碼均可存取到該變量,即使這些程式碼在變數定義之前:

複製程式碼 程式碼如下:

function(){
  console.log(a);//undefined
  var a = "test";
  console.log(a);//test
}

在上述例子中,如果function中a從未被定義,那麼console.log(a)將拋出ReferenceError。當function中對a進行定義後,即使這個定義在a變數呼叫語句之後,對a的呼叫也屬於合法運算(如果對a變數的定義發生在呼叫語句之後,那麼呼叫語句中a變數的值為undefined )。事實上,在function內用var關鍵字進行定義的所有變量,其定義操作都會被提至function的開頭(賦值操作依然留在var定義的那一行),這在JavaScript中稱之為hoisting。例如,上述程式碼就等價於:

複製程式碼 程式碼如下:

function(){
  var a;
  console.log(a);//undefined
  a = "test";
  console.log(a);//test
}

變數的作用域鏈

聯繫JavaScript中變數的儲存,可以很好的理解JS中的「function scope」與hoisting。由於變數是儲存在全域物件或函數呼叫物件上的,因此當在function中定義變數時,無論這個變數定義在function的什麼地方,這次function呼叫所使用的函數呼叫物件中必然會出現一個與此變數同名的屬性。如此一來,function中的任何地方都可以存取到該變數。

涉及函數調用,JavaScript中還有一個更有趣的概念:變數的作用域鏈— 由於變數是儲存在全域物件或函數調用物件上的,因此在存取變數時,可以從多個物件上獲取值。以下面的程式碼為例:

複製程式碼 程式碼如下:

var x = "test";
function(){
  //level-1 function
  var x = "temp";
  function(){
    //level-2 function
    var x = "real";
    //try to access x here. x 將 be "real".
  }
}

在上述程式碼中2級函數(level-2 function)的內部,當試圖存取x變數時,程式可以從3個物件上搜尋對應的屬性值:呼叫2級函數所使用的函數呼叫物件、呼叫1級函數所使用的函數呼叫物件、全域物件— 根據函數定義的巢狀關係,JavaScript將產生一個由全域物件和函數呼叫物件所組成的物件鏈。存取變數時,程式將從離訪問語句最近的那個物件開始搜索,如果沒有搜索到,則在物件鏈中上一層的物件中繼續進行搜索,直至全域物件。

由於這個物件鏈與變數的作用域有關,因此也叫做「作用域鏈」。

如果需要暫時改變作用域鏈,將某個物件插入到作用域鏈的最前端(作為最先存取到的那個函數物件),可以使用with語句:

複製程式碼 程式碼如下:

with(o){
  //code use properties of object o.
}

不過,在JavaScript嚴格模式下,with語句是被禁用的;即使在非嚴格模式下,也不建議使用with語句。

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板