Javascript中的作用域與閉包

2021-09-13 13:12:12 字數 1419 閱讀 4213

什麼是作用域?

在當前執行環境下,可以訪問的變數或函式的範圍。

作用域分為詞法作用域動態作用域

詞法作用域是在js**編譯階段就確定下來的; 對應的,witheval語句會產生動態作用域。

會產生新的作用域的情況:

舉個例子說明作用域

var a = 'hello';

function f1()

f1(); // 1

console.log(a); // hello

可以看到f1中的變數a只能在f1中有效,f1外部訪問不到裡面的a;所以在f1中的a,其作用域就只限定在f1中。

再來個新概念:作用域鏈

var a = 'hello';

function f1()

f1(); // hello

之所以輸出hello, 是因為在f1中並未找到a的定義,此時程式並不會急於拋異常,而是會向呼叫f1的上一層尋找a的定義。如果沒有,會繼續再往上一層的上一層尋找,直到最頂層。

這樣就形成了乙個鏈式的作用域。

什麼是閉包?

通常來講,函式可以訪問函式外面的變數;但是在函式外部,訪問不到在函式裡面定義的變數。

function f1()

console.log(a); // uncaught referenceerror: a is not defined

那麼有沒有可能訪問到f1中的a呢?當然是有的, 看例子:

function f1()

return f2;

}var geta = f1();

console.log(geta()); // 1

我們在f1中,新增了乙個函式f2(實際上f2就可以看做乙個閉包)。

一般情況下,當函式執行完畢時,裡面的變數會被自動銷毀。但是因為我們把f2賦值給了外部的geta,所以f2不會被記憶體釋放,同理f2中使用的a在f2的作用域中,也不會被釋放,所以這個時候就可以訪問到a。

而geta能夠訪問到a,這個在js的編譯階段就已經定型了(詞法作用域)。

官方」的解釋是:閉包是乙個擁有許多變數和繫結了這些變數的環境的表示式(通常是乙個函式),因而這些變數也是該表示式的一部分。

相信很少有人能直接看懂這句話,因為他描述的太學術。其實這句話通俗的來說就是:閉包就是能夠讀取其他函式內部變數的函式。

閉包的特點

閉包可以在函式外部改變函式中的變數的值,如果你把函式作為物件、閉包作為方法、區域性變數作為私有屬性使用,則會改變該變數的值;閉包還會把函式中的變數的值儲存於記憶體中,對記憶體消耗很大,所以濫用閉包的結果就是影響網頁效能,ie中則可能導致記憶體洩露

Javascript中的作用域

所謂作用域,作用就是指讀,寫等操作,而域便是指空間,範圍等 js中的域有 1.scriptscript是全域性的域,相應地裡面的變數就是全域性變數,函式就是全域性函式,如果有多個script包住的域的話,函式會自上而下執行,比如寫了兩的時候便會從上到下先執行第乙個script再執行第二個 scrip...

Javascript的作用域域作用域鏈的理解

如何解析一段可執行 分了兩個階段 解析 和執行 其中解析 可以理解為記名字,就是先把關鍵字var和function定義的變數名登記了下來,這也就有了變數提公升這一說。在執行 階段才是真正的執行賦值,運算等操作。暫不解析這幾個名詞,先來看乙個例子。var scope global function f...

JavaScript 作用域,作用域鏈詳解

前言 es5缺少區域性作用域的概念,而es6已經補充了es6的概念。一 作用域 把作用域比作乙個個封閉的方塊,在相同乙個封閉方塊中的物體可以相互接觸,但是無法和別的封閉方塊中的物體直接接觸。二 全域性作用域 這個就是簡單的全域性作用域。全域性作用域相當於乙個最大的封閉空間,他裡面還有乙個個小的封閉空...