標籤:串連 family 問題 效能 nbsp class 何事 事物 div
想必JS閉包都再熟悉不過了,老生常談的問題,但是還是要囉嗦幾句有人想問,什麼是閉包?用它來做什嗎?
那麼我告訴你,自己去百度搜??
開個玩笑;閉包就是在函數外邊可以讀取到函數內部變數,本質上就是將函數內部和函數外部串連起來的一座橋樑。那麼它有哪些用途呢?
其實剛剛已經提到了,就是在函數外部可以讀取到函數內部的變數,讓變數持久化(變數的值會始終儲存在記憶體中)
閉包的原理和機制
在函數func1內部再定義一個函數func2,將局部變數作為函數func2的傳回值,在函數func2的外邊(func1的裡邊)將func2返回,此時執行函數func1()();兩次即可得到
其實我個人對於一些文字的描述不太感冒,讓我看很多遍可能都看不懂,但是如果給我舉例子的話我是極其感興趣的,那麼己所欲,施於人(語言表達不好,硬拽??),我也來講個案例闡述一下
function func1(){var num1=20;//局部變數num1function func2(){ console.log(num1); return num1;//將num1作為函數func2的函數傳回值 }return func2;將函數func2作為函數func1的傳回值,返回的是func2函數} var a=func1()();//func1()得到的是func2這個函數,func1()()得到的就是函數func2的傳回值num1或者這樣寫 var a=func1(); console.log(a()); 此時就從func1中拿到了num1
這段代碼貌似沒有什麼難度,但是卻實現了想要的到的效果(從func1函數中取出num1的值),此時可能有人不明白,想得到num1很簡單啊,直接在函數func1裡面返回num1不就能得到了嗎,好的下面我們來嘗試一下
function func1(){ var num1=20; return num1; }console.log(func1());此時這段代碼結果確實是得到了20(也就是函數內部的num1)
此時感覺臉火辣辣的熱??,尷尬極了。後來又仔細又思索幾番,覺得不是這麼回事,回頭看了看閉包的用途,其中有一條是讓變數持久化,什麼叫持久化?(動手去查),此時我又要講個案例了??
function func1(){ var num1=20; return num1++; }var a=func1;var b=a();var c=b();console.log(a(),b,c);此時列印的結果都是20
那麼問題來了,變數並沒有持久化?自加操作沒有任何作用,那麼有什麼辦法讓這個變數像其它的變數一樣,此時閉包又派到用場了,
function func1{ var num1=20; function func2(){ console.log(num1); return num1++; } return func2; }var a=func1();var b=a();var c=b();console.log(a(),b,c);此時得到的結果為22,20,21,那麼顯然實現了變數自增的操作
那麼實現變數持久化了(也就是儲存在記憶體中了),而不是執行完函數丟掉了
其實說了這麼多,閉包的用途確實挺大,但是任何事物都有兩面性,有利有弊,閉包也不例外
閉包的缺點就是記憶體消耗很大,就像剛剛說的,它會使變數始終儲存咋記憶體中,所以不能濫用這個閉包,否則後果網頁效能肯定..??
如果接觸過範圍的話,那麼理解閉包應該更容易些(不過我覺得我講的還算清楚了??),簡單提一下範圍
範圍就是變數與函數的可存取範圍,範圍控制著變數與函數的可見度和生命週期
範圍分為兩種:全域範圍和局部範圍,顧名思義,全域範圍就是代碼中的任何地方都能訪問到的對象;局部範圍就是只有自己函數內部才可以訪問的對象
好了,再好的記性都不如動手去操練一下,嘗試一下以上的代碼,基本就差不多了??
JS中的閉包