您好,登錄后才能下訂單哦!
這篇文章主要介紹Javascript作用域與閉包有什么用,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
簡單來說,作用域是指程序中定義變量的區域,它決定了當前執行代碼對變量的訪問權限
在ES5中,一般只有兩種作用域類型:
全局作用域:全局作用域作為程序的最外層作用域,一直存在
函數作用域:函數作用域只有在函數被定義時才會被創建,包含在父級函數作用域或全局作用域中
說完概念,我們來看下面這段代碼:
var a = 100 function test(){ var b = a * 2 var a = 200 var c = a/2 console.log(b) console.log(c) } test() // 這里會打印出什么?
解析:
首先這段代碼形成了全局作用域與函數作用域
全局作用域有一個變量a賦值為100
在test函數作用域中定義了局部變量b,a,c
這里又存在變量提升,在函數作用域內先進行變量提升var b; var a; var c;
再對b進行賦值,這時候a還沒有被賦值,所以a的值為undefined,再將a*2,所以b為NaN
再給a賦值為200,c賦值為a/2等于100
所以最終會打印出 NaN,100
在ES6中,新增了一種塊級作用域
簡單來說,花括號{...}
內的區域就是塊級作用域,但Javascript
并不是原生支持塊級作用域的,需要借助ES6
提出的let
、const
來創建塊級作用域
// ES5 if(true) { var name = '南玖' } console.log(name) // 南玖 // ES6 if(true) { let age = 18 } console.log(age) // 這里會報錯
當可執行代碼內部訪問變量時,會先查找當前作用域下有無該變量,有則立即返回,沒有的話則會去父級作用域中查找...一直找到全局作用域。我們把這種作用域的嵌套機制稱為作用域鏈
詞法作用域
是作用域的一種工作模型,詞法作用域是JavaScript
中使用的一種作用域類型,詞法作用域也可以被叫做靜態作用域
。
所謂的詞法作用域就是在你寫代碼時將變量和作用域寫在哪里來決定的,也就是詞法作用域是靜態的作用域,在你寫代碼時就決定了。函數作用域取決于它申明的位置,與實際調用的位置無關
MDN對閉包的定義:
一個函數和對其周圍(詞法環境)的引用捆綁在一起(或者說函數被引用包圍),這樣一個組合就是閉包(closure
)
也就是說,閉包讓你可以在一個內層函數中訪問到其外層函數的作用域。在JavaScript
中,每當創建一個函數,閉包就會在函數創建的同時被創建出來。
我們可以得出:
閉包 = 函數 + 外層作用域
我們先來看段代碼:
var name = '前端南玖' function say() { console.log(name) } say()
解析:say
函數可以訪問到外層作用域的變量a,那么這樣不就是形成了一個閉包嗎?
在《Javascript權威指南》書中有這樣一句話:嚴格來講,所以JavaScript
函數都是閉包
但這只是理論上的閉包,與我們平時使用的不太一樣。上面這個例子只是一個簡單的閉包。
ECMAScript對閉包的定義:
從理論上來講:所有函數都是閉包。因為它們在創建的時候就已經上層上下文的數據保存起來了。
從實踐上來講:閉包應該滿足兩個條件:1.在代碼中引用了外層作用域的變量;2.即使創建它的上下文已經銷毀,它仍然存在;
我們再看一段《JavaScript權威指南》上的代碼:
let scope = 'global scope' function checkscope(){ let scope = 'local scope' function f(){ return scope } return f } let s = checkscope() s() // 這里返回什么?
很多同學可能覺得是global scope
,但真的是這樣嗎,我們一起來看下它的執行過程:
首先執行全局代碼,創建全局執行上下文,定義全局變量scope
并賦值
申明checkscope
函數,并創建該函數的執行上下文,創建局部變量scope
并賦值
申明f函數,創建該函數的執行上下文
執行checkscope
函數,該函數又返回了一個f函數賦值給了變量s
執行s函數,相當于執行了f函數。這里返回的scope
是local scope
。至于為什么是local scope
,我們上面講到了詞法
作用的基本規則:JavaScript
函數是使用定義它們的作用域來執行的。在定義f函數的作用域中,變量scope
的值為local scope
閉包的應用,絕大多是都是在維護內部變量的場景下使用
由于閉包的存在可能會造成變量常駐內存,使用不當會造成內存泄漏
內存泄漏可能會導致應用程序卡頓或崩潰
var arr = [] for(var i=0;i<3;i++){ arr[i] = function(){ console.log(i) } } arr[0]() // 3 arr[1]() // 3 arr[2]() // 3 // 這里在執行的時候i已經變成了3 // 使用閉包解決 var arr = [] for(var i=0;i<3;i++){ arr[i] = (function(i){ return function(){ console.log(i) } })(i) } arr[0]() // 0 arr[1]() // 1 arr[2]() // 2
以上是“Javascript作用域與閉包有什么用”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。