js之深入理解閉包問題。

2021-08-09 21:44:34 字數 2251 閱讀 9419

最近一段時間準備好好學習下機器學習,所以了解了很多機器學習方面的知識。抓緊補救了下自己曾經遺忘的理論知識(高數、統計學、概率論、微積分等),發現還有點吃力了,很多東西都快忘得差不多。不過,咱程式設計師,還是很擅長圍魏救趙滴^_^。所以,我果斷的選擇邊理論邊著手老本行——程式設計。

選擇語言問題,就是第一大難題。
目前流行的機器學習語言大抵是r語言和python了,熟悉了下r,發現簡直就不該是程式設計師該用的,這簡直就是為非專業程式設計人士準備的東西。大概了解了下,就放棄了。那現在選擇就乙個了,python。

初學python,感覺如魚得水啊。這對把函式式程式設計當成工作的我來說,學起來簡直游刃有餘啊,瞬間被微積分概率論虐得生活不能理解的感覺一去不復返~額,貌似扯遠了。前奏有點太長了,下面進入正題。

閉包?
當我進入python的閉包時,看見了這麼一道題。

# 希望一次返回3個函式,分別計算1x1,2x2,3x3:

defcount

(): fs =

for i in range(1, 4):

deff():

return i*i

return fs

f1, f2, f3 = count()

這不就是曾經那個閉包嗎?現在還記得第一次面試時,面試官問到我閉包時,我一番鬼扯然後用錯誤答案回答的尷尬。既然這樣,我覺得有必要好好和大家分享下我心中的閉包。

閉包是什麼呢?內層函式引用了外層函式的變數(引數也算變數),然後返回內層函式的情況,稱為閉包(closure)。
閉包的特點是返回的函式還引用了外層函式的區域性變數。定義聽起來簡單易懂,能正確應用才是關鍵。上個題的答案是

def

count

(): fs =

for i in range(1, 4):

deff(i) :

defg

() :

return i * i

return g

return fs

f1, f2, f3 = count()

print f1(), f2(), f3()

為什麼會這樣?下面我們用js的方式來處理下另外乙個題目,相信能處理這個新題目,你正確處理這個題目也是很簡單的事。

時間再一次回到第一次面試。面試官出了這麼一道經典題目:請使用閉包輸出1-100每隔一秒輸出一次。額,這個問題怎麼這麼熟悉呢?貌似在**見過,一百道經典面試題還是你必須知道的十道js面試問題來著~,想了半天,就知道要用閉包,要用settimeout。好吧,有這些就夠了,既然一時想不出來,那就直接寫吧!

function

closure

() ) (i)

}, 1000)

}}

貌似有什麼不對。這個大概會輸出一百個100的節奏啊~,可是**不對呢?找了半天,沒發現,那推倒重來!既然是閉包,那不是要return函式麼,那再來過。

function

closure

() }

foo(i)

}, 1000)

}}

這個麼,好像沒有輸出值啊~,左思右想,重來。

for (var i = 0; i < 5; i++) 

}settimeout(a(i),1000)

}

這個像,嗯,不錯,就是他了。然後愉快的將最終結果給面試官過目,面試官問了句,你確定這是我想要的結果?是的,我很確定!現在依舊記得當初的意氣風發啊,年輕真好!

回來之後,把自己把程式在瀏覽器上跑了下,瞬間懵逼了。這不是我想要的結果啊,我想要的結果是100s!最後自己默默的在1000後面乘了個i,最終程式是這樣的:

for (var i = 0; i < 5; i++) 

}settimeout(a(i),i * 1000)

}

但是,為什麼是這樣呢?首先settimeout是乙個定時器,乙個非同步的定時器。什麼意思呢?就是必須主程式跑完了,才開始執行它!意思就是你的for迴圈跑完了,才會執行settimeout。所以如果直接輸出,很明顯,i的值為100.所以你會得到100個100.怎樣才能保留i,讓i按照我們想要的迴圈一下輸出一下呢?那就使用閉包吧,把i傳進去。這樣i的值就被保留下來了,一直被內部的函式引用。所以就能輸出我們想要的結果。最後為什麼要乘以i呢,因為是一秒執行一次,不是過了一秒全部執行!所以~

深入理解JS閉包

閉包 closure 是j acript語言的乙個難點,也是它的特色,很多高階應用都要依靠閉包實現。一 變數的作用域 要理解閉包,首先必須理解j ascript特殊的變數作用域。變數的作用域無非就是兩種 全域性變數和區域性變數。j ascript語言的特殊之處,就在於函式內部可以直接讀取全域性變數。...

深入理解js閉包(快速理解)

一 閉包的基本概念 閉包是函式的一種高階應用方式 通過建立乙個不被銷毀的儲存空間,來在函式的外部呼叫和使用函式內部的資料二 如何定義乙個不被銷毀的執行空間 預設情況下,函式執行完畢,函式執行空間中的程式,也會被銷毀 定義不被銷毀的執行空間的方法 1,在函式內部,返回乙個引用資料型別 陣列,物件,函式...

深入理解閉包

閉包的定義 mdn 對閉包的定義 根據上面的例子,舉乙個例子 var str xiaoqi function getname getname 函式可以返回str這個變數,但str即不是getname函式的區域性變數,也不是foo函式的引數,所以str就是自由變數。這樣函式getname就是乙個閉包。...