重新認識閉包

2021-09-24 06:49:55 字數 1942 閱讀 4306

閉包這個概念作為前端來說算是耳熟能詳了,基本是面試的時候必問的問題,基本上隨便找個前端都能說出點什麼。閉包指的是:能夠訪問另乙個函式作用域的變數的函式。清晰的講:閉包就是乙個函式,這個函式能夠訪問其他函式的作用域中的變數例如下面這個例子eg1:

function

a()

return c

}複製**

通常我們面試的時候都會給這麼乙個例子。 之前面試的人還給我們寫出了這麼乙個例子eg2:

var b = 1

function

a()

複製**

我當時直接就否定了他,說這不是。直到今晚我又一次讀高程的時候,裡面也寫到了這麼乙個例子,我頓時感到一陣後怕,馬上又看了一下閉包的概念。書中說到:該函式能使用函式外定義的變數,那麼我們來看上面的那個例子不正是這樣子的嗎?頓時一頓汗顏。那麼我們來說說閉包的使用場景和優缺點吧。

1.從外部訪問函式的變數

通過上eg1可以看出我們執行a()的時候會給我們返回函式c並且攜帶了變數b,這能為我們做什麼事情呢?看下面乙個例子eg3:

複製**

function

create_counter(initial)

}}var c1 = create_counter()

c1.inc() // 1

c1.inc() // 2

c1.inc() // 3

var c2 = create_counter(10)

c2.inc() // 11

複製**

2.模擬塊級作用域 eg4:

function

count() );

}return arr

}var c1 = count()

var f1 = c1[0]

var f2 = c1[1]

var f3 = c1[2]

複製**

看上面的**我們也許會想到返回的arr是三個函式分別是

c1 = [function() , function() , function() ] 依次呼叫f1,f2,f3會得到1,4,9,但是結果都是16原因就在於返回的函式引用了變數i,但它並非立刻執行。等到3個函式都返回時,它們所引用的變數i已經變成了4,因此最終結果為16。那麼按照閉包的定義我們對以上**做修改 eg5:

function

count() )(i));

}return arr

}var c1 = count()

var f1 = c1[0]

var f2 = c1[1]

var f3 = c1[2]

複製**

這裡使用了匿名函式的自呼叫,在函式內部使用就是乙個閉包,因為它能反問外部函式的任何變數。現在再執行就會得到1,4,9 當然有了es6的let後已經不需要這麼麻煩了。

1.this的指向問題

eg6:

var info = 

}}複製**

因為這裡的執行環境是window了所以這裡的this指向不是info了。

2.記憶體洩露問題 eg7:

function

test()

return innerfunc

}var f1 = test()

f1() // 1

複製**

按照js的**機制是執行完就**,那麼執行完test 變數就應該被**了,但是沒有,因為返回的innerfunc中使用了變數a,所以test不能被**,如何避免呢,那就是執行完以後手動清除。

菜雞乙個,有錯誤請指出。

重新認識container

我還清楚的記得,第一次從 那兒聽說container這個詞 結果他給我解釋了半天還是似懂非懂的。今天,偷閒翻了下posa4,發現裡面對container的解釋特別清楚。粗略的理解下來是,為了分離關注點,而實現的對系統資源的封裝。豁然開朗的發現,os就是應用程式的container。突發奇想的,開發乙...

重新認識測試

以前總覺得測試是軟體開發的邊緣職位,開發人員才是軟體生命週期的核心人員。隨著對網際網路公司的了解,逐步了解到測試的重要性。以bat為例,三家公司均設定了測試開發工程師崗位,該崗位的主要職責就是編寫自動化測試案例,通過對 的邏輯進行分析,設計出能夠覆蓋大部分 的測試用例。如阿里的測試開發工程師的崗位描...

重新認識ARC

雖然用了很久的arc,感受了 簡潔。但是對arc底層實現並不了解。今天抽空研究了下,做些簡單地總結。一 strong 1.區域性變數 對於區域性變數來說,在超出作用域的地方由編譯器自動插入release。大概轉化為 在非arc返回的autorelease型別的方法 在blog手碼大概 如有錯誤還望指...