JavaScript中的變量作用域介紹
對于變量的作用域(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<10; i++){
console.log(i);
}
console.log(i);//i is visible throughout function
}
console.log(i);
console.log(x);
}
在C、Java等“block scope”的語言中,if語句、for語句等邏輯塊結束后,在這些邏輯塊內(nèi)部定義的變量將會被銷毀。JavaScript與之不同,只要一個變量定義在某function內(nèi),那么整個function內(nèi)的所有代碼均可訪問到該變量,即使這些代碼在變量定義之前:
function(){
console.log(a);//undefined
var a = "test";
console.log(a);//test
}
在上述例子中,如果function中a從未被定義,那么console.log(a)將拋出ReferenceError。當function中對a進行定義后,即使這個定義在a變量調(diào)用語句之后,對a的調(diào)用也屬于合法操作(如果對a變量的定義發(fā)生在調(diào)用語句之后,那么調(diào)用語句中a變量的值為undefined)。事實上,在function內(nèi)用var關鍵詞進行定義的所有變量,其定義操作都會被提至function的開頭(賦值操作依然留在var定義的那一行),這在JavaScript中稱之為hoisting。比如,上述代碼就等價于:
function(){
var a;
console.log(a);//undefined
a = "test";
console.log(a);//test
}
變量的作用域鏈
聯(lián)系JavaScript中變量的儲存,可以很好的理解JS中的“function scope”與hoisting。由于變量是儲存在全局對象或者函數(shù)調(diào)用對象上的,因此當在function中定義變量時,無論這個變量定義在function的什么地方,這次function調(diào)用所使用的函數(shù)調(diào)用對象中必然會出現(xiàn)一個與此變量同名的屬性。如此一來,function中的任何地方都可以訪問到該變量。
涉及到函數(shù)調(diào)用,JavaScript中還有一個更有趣的概念:變量的作用域鏈 — 由于變量是儲存在全局對象或者函數(shù)調(diào)用對象上的,因此在訪問變量時,可以從多個對象上獲取值。以下面的代碼為例:
var x = "test";
function(){
//level-1 function
var x = "temp";
function(){
//level-2 function
var x = "real";
//try to access x here. x will be "real".
}
}
在上述代碼中2級函數(shù)(level-2 function)的內(nèi)部,當試圖訪問x變量時,程序可以從3個對象上搜索相應的屬性值:調(diào)用2級函數(shù)所使用的函數(shù)調(diào)用對象、調(diào)用1級函數(shù)所使用的函數(shù)調(diào)用對象、全局對象 — 根據(jù)函數(shù)定義的嵌套關系,JavaScript將生成一個由全局對象和函數(shù)調(diào)用對象所組成的對象鏈。訪問變量時,程序?qū)碾x訪問語句最近的那個對象開始搜索,如果沒有搜索到,則在對象鏈中上一級的對象中繼續(xù)進行搜索,直至全局對象。
由于這個對象鏈與變量的作用域有關,因此也叫做“作用域鏈”。
如果需要臨時改變作用域鏈,將某個對象插入到作用域鏈的最前端(作為最先訪問到的那個函數(shù)對象),可以使用with語句:
with(o){
//code use properties of object o.
}
不過,在JavaScript嚴格模式下,with語句是被禁用的;即使在非嚴格模式下,也不推薦使用with語句。
相關文章
對Layer彈窗使用及返回數(shù)據(jù)接收的實例詳解
今天小編就為大家分享一篇對Layer彈窗使用及返回數(shù)據(jù)接收的實例詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09JavaScript從數(shù)組中刪除特定數(shù)據(jù)的方法總結
js數(shù)組是js部分非常重要的知識,有時我們有這么個需求js數(shù)組刪除指定元素,下面這篇文章主要給大家介紹了關于JavaScript從數(shù)組中刪除特定數(shù)據(jù)的相關資料,需要的朋友可以參考下2022-08-08Omi v1.0.2發(fā)布正式支持傳遞javascript表達式
這篇文章主要介紹了Omi v1.0.2發(fā)布正式支持傳遞javascript表達式,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-03-03不錯的用外部Javascript修正特定網(wǎng)頁內(nèi)容
不錯的用外部Javascript修正特定網(wǎng)頁內(nèi)容...2007-08-08微信小程序?qū)崿F(xiàn)拍照畫布指定區(qū)域生成圖片
這篇文章主要為大家詳細介紹了微信小程序?qū)崿F(xiàn)拍照畫布指定區(qū)域生成圖片,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-07-07js通過iframe加載外部網(wǎng)頁的實現(xiàn)代碼
這篇文章主要介紹了js通過iframe加載外部網(wǎng)頁的實現(xiàn)代碼,需要的朋友可以參考下2015-04-04