【面試系列】之三:關於閉包和遞歸

之三:關於閉包和遞歸

1. 開篇

這一期原本是打算寫閉包的,可是無心中看到《JavaScript高級程序設計》中閉包的前一章就是遞歸。
因此拿出來一塊兒講一下吧!面試

我以爲閉包算是筆試面試中常考的,當面試官問道閉包的時候。或許人人都會說上:從表象上看,閉包是內部函數引用外部函數的變量,致使內部函數引用的變量不會被釋放。即便外部函數被銷燬時,變量依然駐留在內存中!
但是你們真的懂這句話的意思嗎(在深刻了解以前,我也不明白)
今天就讓咱們來好好了解一下:閉包

2. 閉包的原理

先看一段代碼:dom

// 需求時是一秒鐘以後,在控制檯依此輸出1-10
function numberLog() {
    for (var i = 1;i <= 10;i++) {
        setTimeout(function () {
            console.log(i)
        }, 1000)
    }
}
numberLog();

你們以爲上面的代碼,能實現預期的需求嗎?
固然不能,代碼的執行速度很快,咱們循環了十次,生成了十個setTimeout(function(){console.log(i)}, 1000)
而後當一秒鐘過去了,i早就變成11了,因此最後就會輸出10個11函數

那麼怎麼改進呢?
看這段代碼:設計

function numberLog() {
    for (var i = 1;i <= 10;i++) {
        (function (count) {
            setTimeout(function () {
                return console.log(count)
            }, 1000)
        })(i)
    }
}
numberLog();

此次再看一下,在控制檯上會輸出1-10
這是爲何?其實看不懂也沒有關係,就是簡單的舉了一個閉包的應用場景。code

下面具體說一下,只須要記住如下幾點:遞歸

  • 當一個函數執行時,全局會爲這個函數作兩件事:1.構建一個獨立的函數環境 2.把全局的變量用做用域鏈的形式推給這個函數,換句簡單的話說就是讓這個函數能夠訪問到它外層定義的變量,並能夠一層一層的向外引用
  • 若是一個函數裏面嵌套了一個函數,而且這個內部函數引用外層函數的變量,那個這個變量就不能在外層函數結束後被釋放(正常是函數調用完,環境和變量就都會被釋放),由於不知道內部函數在何時就會被調用。

那上面這個例子是怎麼回事呢?
咱們能夠看到在循環代碼內咱們執行了一個函數當即調用,而且返回一個console.log(XX)
因爲當即調用的這個函數引用了外部函數numberLog的變量i,所以i從1-10都不會被釋放,都會在內部造成一個閉包空間。
當一秒鐘過去,仍是會打印出 1-10ip

不知道這麼說,你明白沒有,不太懂的話請看書《JavaScript高級程序設計》第七章閉包那一節。內存

3. 閉包練習題

這個板塊會實時補充的作用域

4. 關於遞歸

其實說到遞歸,主要就是要說callee這個的用法,callee其實主要就是調用本身的外圍函數,而且能夠傳參。
下面咱們來看一個題(我面試百度時的題):

// 用setTimeout來模擬setInterval

先留個懸念哈!

5. 最後

今天是週日,下週會有一個百度糯米的面試!如今感受本身的js的基礎有些薄弱,
因此下一節會說一下js原生的dom操做,一塊兒加油喲!

歡迎你們指出不足和意見,我會虛心接受

相關文章
相關標籤/搜索