我一般都是说,创建一个动态存储空间,突破作用域的限制。让外部可以访问内部的变量,感觉自己答得没什么问题啊,为什么面试完没通知?
ringa_lee
其實閉包沒有那麼高深複雜。
僅從規範的角度:
function a() { var x = 1, y = 2; return function b() { console.log(x + y); } } var f = a(); f();
在執行a期間,我們可以認為它的局部變數存放在一個內部物件Env裡面,a的執行環境保存了Env的引用。
a
Env
定義b的時候,b也會儲存對Env的引用。
b
在a返回時,a的執行環境被銷毀,它對Env的引用也就沒有了。但是,只要b還可以存取(例如,a透過回傳值回傳了b)。那麼b對Env的引用仍然存在,它仍然可以存取Env中保存的局部變數。
將來在函數b執行期間,可以透過所謂的作用域鏈存取x和y。
x
y
這就是閉包。
用圖表示就是:
在函數a回傳前:
在函數a回傳後:
這回答逼格這麼高,沒收到通知一定是面試的單位效率不夠高
你爸生了你這個兒子,你有可以自己賺錢,也可以使用你爸的錢,但是,你不想讓你爸使用你的錢。
映射到js中。 A函數巢狀B函數,B函數中的變數只能在B函數所產生的作用域中使用,A函數無法使用B函數的變數。但是B可以使用A,和全域作用域的變數。
就是引用了外部變數的內部函數。
順便貼下自己以前寫的文章http://scarletsky.github.io/2015/12/02/the-little-javascript-closures/
閉包就是泛函。
R語言不服JS。
a <-function () { x = 1 y = 2 b <- function(){print(x + y)} return(b) } a()() >[1] 3
一個函數存取了它的外部變數就是閉包
可呼叫物件(callable object)。
帳號裡面的錢就是閉包,這是我能想到的對普通人的解釋了...除了帳號擁有者(呼叫者)和銀行(記憶體控制器)之外,誰也不知道裡面到底有沒有錢,雖然帳號相關的東西是暴露的(例如銀行卡,但存摺不符合要求)
前不久我面試也遇到這個問題
閉包是指有權限存取另一個作用域中變數的函數。 一般,函數在執行完後會立刻釋放記憶體。但是,有時候我們需要在希望函數每次執行「記住」上一次的執行結果,而不是立即銷毀。通俗的說,閉包一般用來實現延長記憶力
網路上看到的:閉包其實就是函數的巢狀,內層的函數可以使用外層函數的所有變數,即使外層函數已經執行完畢.
function checkClosure() { //外层函数 var str = 'China'; //局部变量 setTimeout( function() { console.log(str); } //这是一个匿名函数,可以调用外层函数的变量str , 2000); } checkClosure(); console.log('Hello'); //先显示Hello,2秒后显示China.
function裡用var聲明的局部變數在函數執行完就釋放了,function外的聲明的是全局變數,會一直常駐記憶體.checkClosure函數的執行是瞬間的,在checkClosure的函數體內創建了一個局部變數str,checkClosure執行完畢之後str並沒有被釋放,因為setTimeout內的匿名函數存在這對str的引用.待到2秒後函數體內的匿名函數被執行完畢,str才被釋放.
又例如PHP在請求結束時,關閉資料庫連線:
$db = new mysqli('127.0.0.1','user','pass','dbname',3306); register_shutdown_function(function() use ($db) { $db->close(); });
其中資料庫連接$db是匿名函數function()外的變數,PHP跟JS不同之處在於PHP需要使用use明確宣告把變數$db傳入匿名函數中.
其實閉包沒有那麼高深複雜。
僅從規範的角度:
在執行
a
期間,我們可以認為它的局部變數存放在一個內部物件Env
裡面,a
的執行環境保存了Env
的引用。定義
b
的時候,b
也會儲存對Env
的引用。在
a
返回時,a
的執行環境被銷毀,它對Env
的引用也就沒有了。但是,只要b
還可以存取(例如,a
透過回傳值回傳了b
)。那麼b
對Env
的引用仍然存在,它仍然可以存取Env
中保存的局部變數。將來在函數
b
執行期間,可以透過所謂的作用域鏈存取x
和y
。這就是閉包。
用圖表示就是:
在函數
a
回傳前:在函數
a
回傳後:這回答逼格這麼高,沒收到通知一定是面試的單位效率不夠高
你爸生了你這個兒子,你有可以自己賺錢,也可以使用你爸的錢,但是,你不想讓你爸使用你的錢。
映射到js中。
A函數巢狀B函數,B函數中的變數只能在B函數所產生的作用域中使用,A函數無法使用B函數的變數。但是B可以使用A,和全域作用域的變數。
就是引用了外部變數的內部函數。
順便貼下自己以前寫的文章
http://scarletsky.github.io/2015/12/02/the-little-javascript-closures/
閉包就是泛函。
R語言不服JS。
一個函數存取了它的外部變數就是閉包
可呼叫物件(callable object)。
帳號裡面的錢就是閉包,這是我能想到的對普通人的解釋了...除了帳號擁有者(呼叫者)和銀行(記憶體控制器)之外,誰也不知道裡面到底有沒有錢,雖然帳號相關的東西是暴露的(例如銀行卡,但存摺不符合要求)
前不久我面試也遇到這個問題
閉包是指有權限存取另一個作用域中變數的函數。
一般,函數在執行完後會立刻釋放記憶體。但是,有時候我們需要在希望函數每次執行「記住」上一次的執行結果,而不是立即銷毀。通俗的說,閉包一般用來實現延長記憶力
網路上看到的:
閉包其實就是函數的巢狀,內層的函數可以使用外層函數的所有變數,即使外層函數已經執行完畢.
function裡用var聲明的局部變數在函數執行完就釋放了,function外的聲明的是全局變數,會一直常駐記憶體.checkClosure函數的執行是瞬間的,在checkClosure的函數體內創建了一個局部變數str,checkClosure執行完畢之後str並沒有被釋放,因為setTimeout內的匿名函數存在這對str的引用.待到2秒後函數體內的匿名函數被執行完畢,str才被釋放.
又例如PHP在請求結束時,關閉資料庫連線:
其中資料庫連接$db是匿名函數function()外的變數,PHP跟JS不同之處在於PHP需要使用use明確宣告把變數$db傳入匿名函數中.