閉包面試題原題

圖片描述

閉包面試題原題

function fun(n, o) { // ① 
  console.log(o);
  return { // ② 
    fun: function(m) { // ③ 
      return fun(m, n); // ④ 
    }
  };
}

// 第一個例子
var a = fun(0); // 返回undefined
a.fun(1); // 返回 ?
a.fun(2); // 返回 ?
a.fun(3); // 返回 ?

// 第二個例子
var b = fun(0)
  .fun(1)
  .fun(2)
  .fun(3); //undefined,?,?,?

// 第三個例子
var c = fun(0).fun(1);
c.fun(2);
c.fun(3); //undefined,?,?,?

1、關於這個函數的執行過程

先大體說一下這個函數的執行過程:面試

① 初始化一個具名函數,具名函數就是有名字的函數,名字叫 fun。閉包

② 第一個 fun 具名函數執行以後會返回一個對象字面量表達式,即返回一個新的object對象。函數

{ // 這是一個對象,這是對象字面量表達式建立對象的寫法,例如{a:11,b:22}
fun: function(m) {spa

return fun(m, n);

}
}
③ 返回的對象裏面含有fun這個屬性,而且這個屬性裏面存放的是一個新建立匿名函數表達式function(m) {}。code

④ 在③裏面建立的匿名函數會返回一個叫 fun 的具名函數return fun(m, n);,這裏須要說明一下這個 fun 函數返回以後的執行過程:對象

  1. 返回 fun 函數,但默認不執行,由於在 js 裏面,函數是能夠保存在變量裏面的。
  2. 若是想要執行 fun 函數,那麼首先會在當前做用域尋找叫fun 名字的具名函數,可是由於當前做用域裏 fun 名字的函數是沒有被定義的,因此會自動往上一級查找。
    2.1 註解:當前的做用域裏是一個新建立的對象,而且對象裏面只有 fun 屬性,而沒有 fun 具名函數
    2.2 註解:js 做用域鏈的問題,會致使他會不斷地往上級鏈查找。
  3. 在當前做用域沒找到,因此一直往上層找,直到找到了頂層的 fun函數,而後執行這個頂層的 fun 函數。
  4. 而後這兩個 fun 函數會造成閉包,第二個 fun 函數會不斷引用第一個 fun 函數,從而致使一些局部變量例如 n,o 得以保存。

所謂閉包:各類解釋都有,但都不是很接地氣,簡單的來講就是在 js 裏面,有一些變量(內存)能夠被不斷的引用,致使了變量(內存)沒有被釋放和回收,從而造成了一個獨立的存在,這裏涉及了js 的做用域鏈和 js 回收機制,結合二者來理解就能夠了。blog

相關文章
相關標籤/搜索