html5 - 用普通人能听懂的话回答什么是闭包
ringa_lee
ringa_lee 2017-04-17 13:01:28
0
13
1392

我一般都是说,创建一个动态存储空间,突破作用域的限制。让外部可以访问内部的变量,感觉自己答得没什么问题啊,为什么面试完没通知?

ringa_lee
ringa_lee

ringa_lee

全部回覆(13)
巴扎黑

其實閉包沒有那麼高深複雜。

僅從規範的角度:

function a() {
    var x = 1, y = 2;
    return function b() {
        console.log(x + y);
    }
}

var f = a();
f();
  1. 在執行a期間,我們可以認為它的局部變數存放在一個內部物件Env裡面,a的執行環境保存了Env的引用。

  2. 定義b的時候,b也會儲存對Env的引用。

  3. a返回時,a的執行環境被銷毀,它對Env的引用也就沒有了。但是,只要b還可以存取(例如,a透過回傳值回傳了b)。那麼bEnv的引用仍然存在,它仍然可以存取Env中保存的局部變數。

  4. 將來在函數b執行期間,可以透過所謂的作用域鏈存取xy

這就是閉包

用圖表示就是:

  • 在函數a回傳前:

  • 在函數a回傳後:

伊谢尔伦

這回答逼格這麼高,沒收到通知一定是面試的單位效率不夠高

Peter_Zhu

你爸生了你這個兒子,你有可以自己賺錢,也可以使用你爸的錢,但是,你不想讓你爸使用你的錢。

映射到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傳入匿名函數中.

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板