Javascript中的作用域及塊級(jí)作用域
一、塊級(jí)作用域的說明
在學(xué)習(xí)JavaScript的變量作用域之前,我們應(yīng)當(dāng)明確幾點(diǎn):
a、JavaScript的變量作用域是基于其特有的作用域鏈的。
b、JavaScript沒有塊級(jí)作用域。
c、函數(shù)中聲明的變量在整個(gè)函數(shù)中都有定義。
javascript的變量作用域,與平時(shí)使用的類C語言不同,例如C#中的代碼:
static void Main(string[] args) { if(true) { int number=10; } Console.WriteLine(number); }
這段代碼進(jìn)行編譯,是無法通過的,因?yàn)?當(dāng)前上下文不存在number".
因?yàn)檫@里變量的作用域是由花括號(hào)限定的,稱為塊級(jí)作用域。
在塊級(jí)作用域下,所有的變量都在定義的花括號(hào)內(nèi),從定義開始到花括號(hào)結(jié)束這個(gè)范圍內(nèi)可以使用,出了這個(gè)范圍就是無法訪問,也就是說
if(true) { int number=10; Console.WriteLine(number); }
這樣可以訪問,因?yàn)樽兞康亩x與使用在同一個(gè)花括號(hào)內(nèi)。
但是在javascript中沒有塊級(jí)作用域的概念。
二、javascript中的作用域
1、函數(shù)限定變量作用域
在javascript中,函數(shù)里面定義的變量,,可以在函數(shù)里面被訪問,但在函數(shù)外無法訪問,代碼:
<script type="text/javascript"> var num=function() { var number=10; }; try{ alert(number); }catch(e) { alert(e); } </script>
代碼運(yùn)行時(shí),會(huì)拋出一個(gè)異常,變量number沒有定義,是因?yàn)槎x在函數(shù)中的變量無法再函數(shù)外使用,在函數(shù)內(nèi)可以任意使用,即使在賦值之前:
<script type="text/javascript"> var num=function(){ alert(number); var number=10; alert(number); }; try{ num(); }catch(e){ alert(e); } </script>
這段代碼運(yùn)行后,不會(huì)拋出錯(cuò)誤,彈出兩次,分別是undefined和10
2.子域訪問父域
函數(shù)可以限定變量的作用域,那么在函數(shù)中的函數(shù)就為該作用域的子域,在子域中的代碼可以訪問到父域中的變量,代碼如下:
<script type="text/javascript"> var func=function(){ var number=10; var sub_func=function(){ alert(num); }; sub_func(); }; func(); </script>
這段代碼執(zhí)行得到的結(jié)果是10,但是在子域中訪問父域的代碼也是有條件的
<script type="text/javascript"> var func=function(){ var number=10; var sub_func=function(){ var num=20; alert(num); }; sub_func(); }; func(); </script>
這段代碼比前面多了一個(gè)"var num=20;",這句代碼在子域中,那么子域訪問父域的情況就發(fā)生了變化,這段代碼打印的結(jié)果是20,此時(shí)子域訪問的num是子域中的變量,而不是父域中的。由此可見訪問有一定規(guī)則可言,在javascript中使用變量,javascript解釋器首先在當(dāng)前作用域中搜索是否有該變量的定義,如果有,就是用這個(gè)變量,如果沒有就到父域中尋找變量,依次類推,直到最頂級(jí)作用域,仍然沒有找到就拋出異常"變量未定義",代碼如下:
<script type="text/javascript"> (function (){ var num=10; (function (){ var num=20; (function(){ alert(num); })(); })(); })(); </script>
這段代碼執(zhí)行后打印出20,如果將"var num=20
"取掉,那么打印的就是10.同樣去掉"var num=10
",那么就會(huì)出現(xiàn)未定義的錯(cuò)誤。
下面介紹下JS作用域與塊級(jí)作用域
作用域永遠(yuǎn)都是任何一門編程語言中的重中之重,因?yàn)樗刂浦兞颗c參數(shù)的可見性與生命周期。講到這里,首先理解兩個(gè)概念:塊級(jí)作用域與函數(shù)作用域。
什么是塊級(jí)作用域呢?
任何一對花括號(hào)({和})中的語句集都屬于一個(gè)塊,在這之中定義的所有變量在代碼塊外都是不可見的,我們稱之為塊級(jí)作用域。
函數(shù)作用域就好理解了(*^__^*) ,定義在函數(shù)中的參數(shù)和變量在函數(shù)外部是不可見的。
大多數(shù)類C語言都擁有塊級(jí)作用域,JS卻沒有。請看下文demo:
//C語言 #include <stdio.h> void main() { int i=2; i--; if(i) { int j=3; } printf("%d/n",j); }
運(yùn)行這段代碼,會(huì)出現(xiàn)“use an undefined variable:j”的錯(cuò)誤。可以看到,C語言擁有塊級(jí)作用域,因?yàn)閖是在if的語句塊中定義的,因此,它在塊外是無法訪問的。
而JS是如何表現(xiàn)的呢,再看另一個(gè)demo:
functin test(){ for(var i=0;i<3;i++){ } alert(i); } test();
運(yùn)行這段代碼,彈出"3",可見,在塊外,塊中定義的變量i仍然是可以訪問的。也就是說,JS并不支持塊級(jí)作用域,它只支持函數(shù)作用域,而且在一個(gè)函數(shù)中的任何位置定義的變量在該函數(shù)中的任何地方都是可見的。
那么我們該如何使JS擁有塊級(jí)作用域呢?是否還記得,在一個(gè)函數(shù)中定義的變量,當(dāng)這個(gè)函數(shù)調(diào)用完后,變量會(huì)被銷毀,我們是否可以用這個(gè)特性來模擬出JS的塊級(jí)作用域呢?看下面這個(gè)DEMO:
function test(){ (function (){ for(var i=0;i<4;i++){ } })(); alert(i); } test();
這時(shí)候再次運(yùn)行,會(huì)彈出"i"未定義的錯(cuò)誤,哈哈,實(shí)現(xiàn)了吧~~~這里,我們把for語句塊放到了一個(gè)閉包之中,然后調(diào)用這個(gè)函數(shù),當(dāng)函數(shù)調(diào)用完畢,變量i自動(dòng)銷毀,因此,我們在塊外便無法訪問了。
JS的閉包特性is the most important feature((*^__^*) 大家懂的)。在JS中,為了防止命名沖突,我們應(yīng)該盡量避免使用全局變量和全局函數(shù)。那么,該如何避免呢?不錯(cuò),正如上文demo所示,我們可以把要定義的所有內(nèi)容放入到一個(gè)
(function (){ //內(nèi)容 })();
總結(jié)
以上所述是小編給大家介紹的Javascript中的作用域及塊級(jí)作用域,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
- 深入理解JavaScript中的塊級(jí)作用域、私有變量與模塊模式
- JavaScript的作用域和塊級(jí)作用域概念理解
- 為什么JavaScript沒有塊級(jí)作用域
- JavaScript匿名函數(shù)之模仿塊級(jí)作用域
- 解析JavaScript模仿塊級(jí)作用域
- 通過函數(shù)作用域和塊級(jí)作用域看javascript的作用域鏈
- JavaScript使用閉包模仿塊級(jí)作用域操作示例
- js類中的公有變量和私有變量
- javascript 動(dòng)態(tài)生成私有變量訪問器
- JavaScript私有變量實(shí)例詳解
- JS塊級(jí)作用域和私有變量實(shí)例分析
相關(guān)文章
基于JavaScript怎么實(shí)現(xiàn)讓歌詞滾動(dòng)播放
各種音樂播放器上都有一個(gè)自動(dòng)滾動(dòng)播放歌詞的功能,當(dāng)前滾動(dòng)到的歌詞會(huì)高亮居中顯示,即使歌詞被換行也能正常居中,那么這個(gè)功能基于JavaScript怎么實(shí)現(xiàn)讓歌詞滾動(dòng)播放呢?感興趣的朋友一起看看吧2015-11-11當(dāng)json鍵為數(shù)字時(shí)的取值方法解析
對于數(shù)字鍵名或者非正常變量字符(比如有空格),必須使用 aa[x]的方式2013-11-11JavaScript筆記之?dāng)?shù)據(jù)屬性和存儲(chǔ)器屬性
本文給大家介紹js數(shù)據(jù)屬性和存儲(chǔ)器屬性,及兩種屬性的區(qū)別,對js數(shù)據(jù)屬性存儲(chǔ)器屬性相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)2016-03-03通過實(shí)例了解Render Props回調(diào)地獄解決方案
這篇文章主要介紹了通過實(shí)例了解Render Props回調(diào)地獄解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11javascript實(shí)現(xiàn)的猜數(shù)小游戲完整實(shí)例代碼
這篇文章主要介紹了javascript實(shí)現(xiàn)的猜數(shù)小游戲,游戲中用戶共有10次猜測機(jī)會(huì),并且每次都有不同的提示信息,該游戲涉及javascript流程控制與數(shù)值運(yùn)算的相關(guān)技巧,需要的朋友可以參考下2016-05-05