前端面試系列 JS中的閉包 來龍去脈

2021-08-26 20:51:27 字數 2745 閱讀 6735

經歷過面試的前端人被問得做多的乙個話題或許就是js的閉包了吧,就好像高考中總要出些難題來拉開不同人的差距,而閉包就是如此,哪怕平時用的不多,但是因為其特殊性總被拿來衡量乙個前端人的js掌握情況。

以前也陸陸續續看過不少資料,書籍,對其的解釋五碼八門,大差不差,但從來無法回答自己幾個核心問題(例如為啥叫closure,到底使用場景是什麼),所以一直無法深入去理解,也就更別提靈活的使用了。

最近查閱資料時發現w3school中對其的介紹頗為深入,翻譯給大家,希望對大家有所啟迪和幫助。

w3school不清楚原因被牆了,明顯純技術的**

js中的變數可以是屬於local的或是全域性global的。global變數可以利用closure閉包技術變成local本地的。

乙個函式可以獲取函式內部所有的變數,就像下面這樣(感覺像廢話)

example

function

myfunction

()

但函式通過可以獲取外面定義的變數(js特色):

example

var a = 4;

function

myfunction

()

在上乙個例子中,a是乙個全域性的變數。在乙個網頁中,全域性變數屬於window物件。當然了,全域性變數可以在頁面的所有指令碼中被使用和修改。在第乙個例子中,a是乙個區域性變數。乙個區域性變數只能被用在函式定義的地方,對於其他函式和指令碼是隔離的。

全域性變數和區域性變數就算名字取得一樣了,還是不同的變數,改變其中乙個,另乙個不受影響。

如果變數建立的時候是不帶關鍵字var的,那就都是全域性變數,哪怕他們是在函式內部的定義的。

全域性變數存活的時間就是應用(可以是window或是你的網頁)存在的時間。區域性變數生命可就更短了,在幻術被呼叫的時候建立,然後在函式結束的時候被刪除掉。

翻譯的不好,其實不是悖論,更確切的說是一種兩難的境地,沒有好的辦法來處理這個計數器,當然後面得通過閉包來實現

假定你想要借助某個變數來統計某些東西,而且你希望所有的函式都可以使用這個。你當然可以使用乙個全域性變數和乙個函式來實現上面的需求:

example

// initiate counter

var counter = 0;

// function to increment counter

function

add()

// call

add() 3 times

add();

add();

add();

// the counter should now be 3

上面的方案存在乙個問題,頁面上的**可以直接修改這個全域性變數counter,而且不需要呼叫add(而我們希望的是counter只作為add的私有變數來處理)

example

// initiate counter

var counter = 0;

// function to increment counter

function

add()

// call

add() 3 times

add();

add();

add();

//the counter should now be 3. but it is 0

完全不起作用,因為我們顯示的是全域性變數的counter而不是區域性的counter。我們可以通過讓函式返回它來使刪除全域性變數counter而只訪問區域性的counter。

example

// function to increment counter

function

add()

// call

add() 3 times

add();

add();

add();

//the counter should now be 3. but it is 1.

還是不起作用,因為我們在每次呼叫函式的時候都重置了區域性變數counter。而乙個js的內部函式就可以解決這個問題。

所有的函式都可以訪問全域性的作用域。事實上,在js中,所有的函式都可以訪問父域的變數。js支援巢狀函式,巢狀函式就可以訪問父域。在下面的例子中,內部函式plus()可以在父函式中訪問counter變數。

example

function

add()

plus();

return counter;

}

這可以解決counter的兩難情況,只要我們可以在外部獲取到plus函式。我們需要讓counter=0只執行一次。因此我們需要closure,閉包。

還記得自呼叫函式麼,來看看下面的函式:

example

var add = (function

() })();

add();

add();

add();

// the counter is now 3

變數add 設定了自呼叫函式來返回乙個函式。自呼叫函式正好只執行一次,實現了counter的初始化。這就是乙個js的閉包,它能夠讓乙個函式有自己私有的變數。counter的作用域被限制在匿名函式中,而且只能通過add函式來改變。所以說閉包就是乙個能夠獲取父域的函式,即使父函式已經關了。

前端面試題 變數提示,閉包 作用域

1.變數提公升 1.函式提公升,先把函式提到最前面,然後是變數提公升 var value 1 var test function 賦值 var test function 裡面的value 提公升,先執行 var value 然後執行console.log value 所以輸出 undefined ...

2018前端面試總結js部分 中

1.語法 function 函式名 引數1 引數2 function fx function 匿名函式 2.字面量 var fn function 3.通過函式物件方式 var x new function 複製 1 函式名 function getsum getsum 2 自呼叫 function...

2018前端面試總結js部分 中

1.語法 function 函式名 引數1 引數2 function fx function 匿名函式 2.字面量 var fn function 3.通過函式物件方式 var x new function 複製 1 函式名 function getsum getsum 2 自呼叫 function...