這次帶給大家js的作用域使用詳解,js作用域使用的注意事項有哪些,下面就是實戰案例,一起來看一下。
JavaScript是現在很多人都在使用的,對於JavaScript的使用,可能很多人還不是很清楚作用域以及塊級作用域,這裡文章就給大家具體的說明下,想了解的一起來看看。
一、區塊級作用域的說明
# 在學習JavaScript的變數作用域之前,我們應先明確幾點:
# a、JavaScript的變數作用域是基於其特有的作用域鏈的。
b、JavaScript沒有區塊級作用域。
c、函數中宣告的變數在整個函數中都有定義。
javascript的變數作用域,與平常使用的類別C語言不同,例如C#中的程式碼:
static void Main(string[] args) { if(true) { int number=10; } Console.WriteLine(number); }
這段程式碼進行編譯,是無法通過的,因為"目前上下文不存在number".
因為這裡變數的作用域是由花括號限定的,稱為區塊級作用域。
在區塊級作用域下,所有的變數都在定義的花括號內,從定義開始到花括號結束這個範圍內可以使用,出了這個範圍就是無法訪問,也就是說
if(true) { int number=10; Console.WriteLine(number); }
這樣可以訪問,因為變數的定義與使用在同一個花括號內。
但是在javascript中沒有區塊級作用域的概念。
二、javascript中的作用域
# 1.函數限定變數作用域
在javascript中,函數裡面定義的變量,,可以在函數裡面被訪問,但在函數外無法訪問,程式碼:
<script type="text/javascript"> var num=function() { var number=10; }; try{ alert(number); }catch(e) { alert(e); } </script>
程式碼執行時,會拋出一個異常,變數number沒有定義,是因為定義在函數中的變數無法再函數外使用,在函數內可以任意使用,即使在賦值之前:
<script type="text/javascript"> var num=function(){ alert(number); var number=10; alert(number); }; try{ num(); }catch(e){ alert(e); } </script>
這段程式碼運行後,不會拋出錯誤,彈出兩次,分別是undefined和10
2.子網域存取父域
函數可以限定變數的作用域,那麼在函數中的函數就為該作用域的子域,在子域中的程式碼可以存取到父域中的變量,程式碼如下:
<script type="text/javascript"> var func=function(){ var number=10; var sub_func=function(){ alert(num); }; sub_func(); }; func(); </script>
這段程式碼執行得到的結果是10,但是在子網域中存取父域的程式碼也是有條件的
<script type="text/javascript"> var func=function(){ var number=10; var sub_func=function(){ var num=20; alert(num); }; sub_func(); }; func(); </script>
這段程式碼比前面多了一個"var num=20;",這句程式碼在子域中,那麼子域訪問父域的情況就發生了變化,這段程式碼列印的結果是20,此時子域存取的num是子域中的變量,而不是父域中的。由此可見訪問有一定規則可言,在javascript中使用變量,javascript解釋器首先在當前作用域中搜索是否有該變量的定義,如果有,就是用這個變量,如果沒有就到父域中尋找變量,依序類推,直到最頂級作用域,仍然沒有找到就拋出異常"變數未定義",程式碼如下:
<script type="text/javascript"> (function (){ var num=10; (function (){ var num=20; (function(){ alert(num); })(); })(); })(); </script>
這段程式碼執行後印出20,如果將"var num=20
"取掉,那麼列印的就是10.同樣去掉"var num=10
",那麼就會出現未定義的錯誤。
以下介紹下JS作用域與區塊級作用域
作用域永遠是任何一門程式語言中的重中之重,因為它控制變數與參數的可見性與生命週期。講到這裡,首先理解兩個概念:區塊級作用域與函數作用域。
什麼是區塊級作用域呢?
任何一對花括號({和})中的語句集都屬於一個區塊,在這之中定義的所有變數在程式碼區塊外都是不可見的,我們稱之為區塊級作用域。
函數作用域就好理解了(*^^*) ,定義在函數中的參數和變數在函數外部是不可見的。
大多數類別C語言都擁有區塊級作用域,JS卻沒有。請看下文demo:
//C语言 #include <stdio.h> void main() { int i=2; i--; if(i) { int j=3; } printf("%d/n",j); }
运行这段代码,会出现“use an undefined variable:j”的错误。可以看到,C语言拥有块级作用域,因为j是在if的语句块中定义的,因此,它在块外是无法访问的。
而JS是如何表现的呢,再看另一个demo:
functin test(){ for(var i=0;i<3;i++){ } alert(i); } test();
运行这段代码,弹出"3",可见,在块外,块中定义的变量i仍然是可以访问的。也就是说,JS并不支持块级作用域,它只支持函数作用域,而且在一个函数中的任何位置定义的变量在该函数中的任何地方都是可见的。
那么我们该如何使JS拥有块级作用域呢?是否还记得,在一个函数中定义的变量,当这个函数调用完后,变量会被销毁,我们是否可以用这个特性来模拟出JS的块级作用域呢?看下面这个DEMO:
function test(){ (function (){ for(var i=0;i<4;i++){ } })(); alert(i); } test();
这时候再次运行,会弹出"i"未定义的错误,哈哈,实现了吧~~~这里,我们把for语句块放到了一个闭包之中,然后调用这个函数,当函数调用完毕,变量i自动销毁,因此,我们在块外便无法访问了。
JS的闭包特性is the most important feature((*^^*) 大家懂的)。在JS中,为了防止命名冲突,我们应该尽量避免使用全局变量和全局函数。那么,该如何避免呢?不错,正如上文demo所示,我们可以把要定义的所有内容放入到一个
(function (){ //内容 })();
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上是js的作用域使用詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!