JavaScript作用域

JavaScript作用域

1.作用域

JavaScript的作用域與C、Java等語(yǔ)言不同,它不是以花括號(hào)包圍的塊級(jí)作用域,這個(gè)特性經(jīng)常被大多數(shù)人忽視。例如下面代碼,在大多數(shù)類(lèi)C的語(yǔ)言中會(huì)出現(xiàn)變量未定義的錯(cuò)誤,但在JavaScript中卻完全合法:

if (true) {

? ? ? var msg = 'msg';

}

console.log(msg); // 輸出 msg;


這是因?yàn)镴avaScript的作用域完全是由函數(shù)來(lái)決定的,if、for語(yǔ)句中的花括號(hào)不是獨(dú)立的作用域。

2.函數(shù)作用域

不同于大多數(shù)類(lèi)C的語(yǔ)言,由一對(duì)花括號(hào)封閉的代碼塊就是一個(gè)作用域,JavaScript的作用域是通過(guò)函數(shù)來(lái)定義的,在一個(gè)函數(shù)中定義的變量只對(duì)這個(gè)函數(shù)內(nèi)部可見(jiàn),我們稱(chēng)為函數(shù)作用域。在函數(shù)中引用一個(gè)變量時(shí),JavaScript會(huì)先搜索當(dāng)前函數(shù)作用域,如果沒(méi)有找到則搜索其上層作用域,一直到全局作用域。下面是一個(gè)簡(jiǎn)單的例子:

var scope = 'global';

var f1 = function() {

? ? ? ?console.log(scope);

}

f1(); // 輸出 global

var f2 = function() {

var scope = 'f2';

? ? ?console.log(scope);

}

f2(); // 輸出 f2


以上示例十分明了,JavaScript的函數(shù)定義是可以嵌套的,每一層是一個(gè)作用域,變量搜索順序是從內(nèi)到外,按照作用域搜索順序,在console.log函數(shù)訪問(wèn)scope變量時(shí),JavaScript會(huì)先搜索函數(shù)f2的作用域,恰巧在f2的作用域里搜索到了scope變量,所以上層作用域中定義的scope就被屏蔽了。但下面這個(gè)例子可能就有些讓人困惑:

var scope = 'global';

var f3 = function() {

console.log(scope);

var scope = 'f3';

}

f3(); // 輸出 undefined

復(fù)制代碼

上面的代碼可能和你的預(yù)想不一樣,并沒(méi)有輸出global,而是undefined,這是為什么吶?這是JavaScript的一個(gè)特性,就是變量聲明語(yǔ)句永遠(yuǎn)在該作用域里最先被執(zhí)行,所以上面的例子形同如下:

var scope = 'global';

var f4 = function() {

var scope; // 變量聲明最先被執(zhí)行

console.log(scope);

scope = 'f4'; //變量被賦予值

}

f4(); // 輸出 undefined


這樣就不難理解運(yùn)行f3()函數(shù)為什么沒(méi)輸出global,而是undefined了。

3.函數(shù)作用域的嵌套

一個(gè)作用域嵌套的例子:

var f5 = function() {

var scope = 'first';

(function() {

var scope = 'second';

(function() {

console.log(scope);

}());

}());

}

f5(); // 輸出 second


我們?cè)谧顑?nèi)層函數(shù)中引用到了scope變量,通過(guò)作用域搜索,找到了其父作用域中定義的scope變量。

有一點(diǎn)要注意:函數(shù)作用域的嵌套關(guān)系是在定義時(shí)決定的,而不是在調(diào)用時(shí)決定的,下面是一個(gè)簡(jiǎn)單的例子:

var scope = 'global';

var f6 = function() {

console.log(scope);

}

var f7 = function() {

var scope = 'f7';

f6();

}

f7(); // 輸出 global


這個(gè)例子中,通過(guò)f7調(diào)用的f6在搜索scope時(shí),找到的是f6函數(shù)的父作用域中定義的scope變量,而不是f7中定義的scope變量。這說(shuō)明了函數(shù)作用域的嵌套關(guān)系是在定義時(shí)決定的,而不是在調(diào)用時(shí)決定的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 目錄 1.靜態(tài)作用域與動(dòng)態(tài)作用域 2.變量的作用域 3.JavaScript 中變量的作用域 4.JavaScri...
    一縷殤流化隱半邊冰霜閱讀 7,274評(píng)論 37 113
  • 摘?。篽ttp://www.cnblogs.com/rainman/archive/2009/04/28/1445...
    潔芬閱讀 332評(píng)論 0 0
  • 作用域是變量與函數(shù)的可訪問(wèn)范圍,作用域控制著變量與函數(shù)的可見(jiàn)性和生命周期。變量的作用域有兩種:全局作用域和局部作用...
    lulu_c閱讀 628評(píng)論 0 2
  • 一. 作用域 所有編程語(yǔ)言都有一最基本的功能,就是能夠存儲(chǔ)變量當(dāng)中的值,并且能在之后對(duì)這個(gè)值進(jìn)行訪問(wèn)或者修改。 那...
    忘記曾經(jīng)出發(fā)的目的閱讀 293評(píng)論 0 0
  • 作者簡(jiǎn)介: 一位地才,平平凡凡,普普通通,和大多數(shù)人一樣喜歡文字。最?lèi)?ài)的作者是前輩太宰治,因此文風(fēng)與他類(lèi)似。滿(mǎn)面...
    荊蓗閱讀 1,005評(píng)論 4 18

友情鏈接更多精彩內(nèi)容