JS----JavaScript中的作用域和作用域链
作用域(Scope)
1.什么是作用域
作用域是在運(yùn)行時代碼中的某些特定部分中變量,函數(shù)和對象的可訪問性。
作用域(scope):一個變量的可用范圍
作用域的類型
Javascript中有三種作用域:
- 全局作用域;
- 函數(shù)作用域;
- 塊級作用域;
2. 全局作用域
任何不在函數(shù)中或是大括號中聲明的變量,都是在全局作用域下,全局作用域下聲明的變量可以在程序的任意位置訪問。
例如:
3. 函數(shù)作用域
函數(shù)作用域也叫局部作用域,如果一個變量是在函數(shù)內(nèi)部聲明的它就在一個函數(shù)作用域下面。這些變量只能在函數(shù)內(nèi)部訪問,不能在函數(shù)以外去訪問。
例如:
4. 塊級作用域
ES6引入了let和const關(guān)鍵字,和var關(guān)鍵字不同,在大括號中使用let和const聲明的變量存在于塊級作用域中。在大括號之外不能訪問這些變量。
例如:
上面代碼中可以看出,在大括號內(nèi)使用var聲明的變量lang是可以在大括號之外訪問的。使用var聲明的變量不存在塊級作用域中。
5.作用域嵌套
像Javascript中函數(shù)可以在一個函數(shù)內(nèi)部聲明另一個函數(shù)一樣,作用域也可以嵌套在另一個作用域中。
例如:
這里我們有三層作用域嵌套,首先第一層是一個塊級作用域(let聲明的),被嵌套在一個函數(shù)作用域(greet函數(shù))中,最外層作用域是全局作用域。
6.詞法作用域
詞法作用域(也叫靜態(tài)作用域)從字面意義上看是說作用域在詞法化階段(通常是編譯階段)確定而非執(zhí)行階段確定的。
例如:
上面代碼可以看出無論printNumber()在哪里調(diào)用console.log(number)都會打印42。動態(tài)作用域不同,console.log(number)這行代碼打印什么取決于函數(shù)printNumber()在哪里調(diào)用。
如果是動態(tài)作用域,上面console.log(number)這行代碼就會打印54。
使用詞法作用域,我們可以僅僅看源代碼就可以確定一個變量的作用范圍,但如果是動態(tài)作用域,代碼執(zhí)行之前我們沒法確定變量的作用范圍。
像C,C++,Java,Javascript等大多數(shù)編程語言都支持靜態(tài)作用域。Perl 既支持動態(tài)作用域也支持靜態(tài)作用域。
在js中詞法作用域規(guī)則:
- 函數(shù)允許訪問函數(shù)外的數(shù)據(jù)
- 整個代碼結(jié)構(gòu)中只有函數(shù)可以可以限定作用域
- 作用域規(guī)則首先使用提升規(guī)則分析
- 如果當(dāng)前作用域中有名字了,就不考慮外面的名字
7. 作用域鏈
當(dāng)在Javascript中使用一個變量的時候,首先Javascript引擎會嘗試在當(dāng)前作用域下去尋找該變量,如果沒找到,再到它的上層作用域?qū)ふ?#xff0c;以此類推直到找到該變量或是已經(jīng)到了全局作用域。
如果在全局作用域里仍然找不到該變量,它就會在全局范圍內(nèi)隱式聲明該變量(非嚴(yán)格模式下)或是直接報(bào)錯。
例如:
// 案例 1: function f1(){function f2(){} }var num = 456; function f3(){function f4(){} } // 案例2 function f1() {var num = 123;function f2() {console.log( num );}f2(); } var num = 456; f1();總結(jié)
以上是生活随笔為你收集整理的JS----JavaScript中的作用域和作用域链的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS 13.4 测试版描述文件升级方法
- 下一篇: JS----javascript原型和原