關於閉包的幾點認識

2022-05-05 15:06:12 字數 2889 閱讀 8494

什麼是閉包?

閉包一般人都說, 是函式中定義的乙個函式,有的人也說函式中套函式。 

其實準確點說,閉包是乙個能夠訪問到其他函式內部變數的函式,

當然這個其他函式不是父子關係的函式, 而是兄弟關係的函式。

舉個最簡單的例子引導一下

function

alwayslinger()

console.log( num ); //

num is not defined;

在外面訪問 num 肯定是訪問不到,還會報錯:num is not defined;

但是你又想訪問到 alwayslinger 函式內部的區域性變數。

這是時候你就需要閉包了。

function

alwayslinger()

}console.log(

alwayslinger()());

//0;

看起來,好像也沒有什麼神奇之處,當你呼叫alwayslinger函式後,返回乙個函式,執行返回的函式,再次返回 num 變數。

這樣就取了函式內部的值。看到這裡你可能你會迷惑, 為什麼要返回乙個函式,然後再返回num呢,直接返回num不好嗎?

我建議你帶著這個疑問看下去。

閉包其實是一種現象:

父函式內的子函式,被父函式之外的變數引用,父函式裡的變數永遠不會銷毀(也說明了js的垃圾**機制不會生效,父函式中的變數永遠存在)

下面舉幾個例子,簡單的說明閉包常見的運用場景。

1、使變數始終存在記憶體中

function

alwayslinger()

}console.log( alwayslinger()() ); //0

console.log( alwayslinger()() ); //

0console.log( alwayslinger()() ); //

0console.log( alwayslinger()() ); //

0var func =alwayslinger();

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

console.log( func() ); //

2console.log( func() ); //

3console.log( func() ); //

4console.log( func() ); //

5

前幾個console,輸出同乙個值,是因為每次執行都返回乙個新值,

後幾個console,輸出遞增的值,是因為每次執行後操作的都是乙個值,就是函式中的區域性變數num。我們使用閉包不單單只是為了取到區域性變數,還要去操縱它。

2、模擬塊級作用域

比如,我們現在要實現點選列表,實現彈出列表的索引值。

//

先獲取到列表項 li

var list = document.queryselectorall("li");

//遍歷 li

for (var i = 0; i < list.length; i++)

}

一起看起來,好像並沒有什麼毛病,但是執行的結果卻是不管點選那個都是返回最後乙個索引值。這是因為在es5中沒有塊級作用域的原因導致的, 解決的辦法很多種舉幾種常用的解決辦法。

1、閉包方式

var list = document.queryselectorall("li");

for (var i = 0; i < list.length; i++)

})(i)

}//迴圈內部加乙個自執行函式,利用函式作用域,模擬塊級作用域。

2、利用let代替var宣告, 告訴瀏覽器使用es6語法

var list = document.queryselectorall("li");

for (let i = 0; i < list.length; i++)

}3、 使用foreach 迴圈

var list = document.queryselectorall("li");

list.foreach(

function

(item,i)

})2,3兩種方法跟今天沒有關係,這裡就不多做討論。

來乙個比較坑的面試題。

function

createfunction ()   

}  return

result;

}var afunction =createfunction ();

afunction.foreach(

function

(obj))

大家可以自己嘗試著猜猜,結果是什麼?

再來乙個差不多的面試題。

for (var i = 0; i < 10; i++) , 0);

}

細心的小夥伴或許已經發現了,這種比較迷惑人的面試題,都有乙個共同的特徵,就是在迴圈中包含了乙個函式。只要遇到這種問題,都可以用閉包來解決。

3、代替全域性變數

我們都知道如果乙個程式全域性變數太多的話,會影響效能, 那麼怎麼解決呢,其實最根本的就是把全域性變數變成區域性變數;

(function

()  test();

/*..... 一堆堆邏輯 .....

*/})()

console.log(name)

//name not defined;

// 這樣的話,在外界就訪問不到變數了,避免了全域性變數的增多。---恢復內容結束---

# 閉包

以上就是我對閉包的理解,如果有錯誤的地方請提出,歡迎批評指正。一起學習一起進步。

再次認識閉包

1 官方一點說,能夠讀取其他函式內部的區域性變數的函式,即為閉包。抓住幾個點 2 從表現上來認識 乙個函式a裡定義了另乙個函式b,b讀取了a的區域性變數 3 從特性上去認識 函式內定義的區域性變數,會隨著函式的執行完畢而被銷毀,記憶體被 但是在閉包存在的情況下,區域性變數被閉包函式引用,因此沒有被立...

關於STRUCT的幾點認識

1.struct 的巨大作用 面對乙個人的大型 c c 程式時,只看其對struct 的使用情況我們就可以對其編寫者的程式設計經 驗進行評估。因為乙個大型的c c 程式,勢必要涉及一些 甚至大量 進行資料組合的結構體,這些結 構體可以將原本意義屬於乙個整體的資料組合在一起。從某種程度上來說,會不會用...

關於C C 的幾點認識

從學習c語言開始,已經接觸這門語言好幾年了,不敢說有多精通,本文就本人以往遇到過的幾個問題做乙個說明。1 認識c語言的安全隱患。首先,我們來看乙個簡單的例子。int ndata 50 char szbuf 20 memset szbuf,0,20 strcpy szbuf,const char nd...