国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

一道js閉包面試題的學(xué)習(xí)

plus2047 / 3151人閱讀

摘要:然后最外層這個函數(shù)會返回一個新對象,對象里面有一個屬性,名為,而這個屬性的值是一個匿名函數(shù),它會返回。

最近看到一條有意思的閉包面試題,但是看到原文的解析,我自己覺得有點迷糊,所以自己重新做一下這條題目。

閉包面試題原題
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,?,?,?
一、關(guān)于這個函數(shù)的執(zhí)行過程

先大致說一下這個函數(shù)的執(zhí)行過程:

① 初始化一個具名函數(shù),具名函數(shù)就是有名字的函數(shù),名字叫 fun。

② 第一個 fun 具名函數(shù)執(zhí)行之后會返回一個對象字面量表達(dá)式,即返回一個新的object對象。

{  // 這是一個對象,這是對象字面量表達(dá)式創(chuàng)建對象的寫法,例如{a:11,b:22}
  fun: function(m) { 
    return fun(m, n); 
  }
}

③ 返回的對象里面含有fun這個屬性,并且這個屬性里面存放的是一個新創(chuàng)建匿名函數(shù)表達(dá)式function(m) {}

④ 在③里面創(chuàng)建的匿名函數(shù)會返回一個叫 fun 的具名函數(shù)return fun(m, n);,這里需要說明一下這個 fun 函數(shù)返回之后的執(zhí)行過程:

1. 返回 fun 函數(shù),但默認(rèn)不執(zhí)行,因為在 js 里面,函數(shù)是可以保存在變量里面的。

2. 如果想要執(zhí)行 fun 函數(shù),那么首先會在當(dāng)前作用域?qū)ふ医衒un 名字的具名函數(shù),但是因為當(dāng)前作用域里 fun 名字的函數(shù)是沒有被定義的,所以會自動往上一級查找。
    2.1 注解:當(dāng)前的作用域里是一個新創(chuàng)建的對象,并且對象里面只有 fun 屬性,而沒有 fun 具名函數(shù)
    2.2 注解:js 作用域鏈的問題,會導(dǎo)致他會不斷地往上級鏈查找。

3. 在當(dāng)前作用域沒找到,所以一直往上層找,直到找到了頂層的 fun函數(shù),然后執(zhí)行這個頂層的 fun 函數(shù)。

4. 然后這兩個 fun 函數(shù)會形成閉包,第二個 fun 函數(shù)會不斷引用第一個 fun 函數(shù),從而導(dǎo)致一些局部變量例如 n,o 得以保存。
所謂閉包:各種解釋都有,但都不是很接地氣,簡單的來說就是在 js 里面,有一些變量(內(nèi)存)可以被不斷的引用,導(dǎo)致了變量(內(nèi)存)沒有被釋放和回收,從而形成了一個獨立的存在,這里涉及了js 的作用域鏈和 js 回收機(jī)制,結(jié)合兩者來理解就可以了。
二、第一個例子的輸出結(jié)果分析 1. var a = fun(0); // 返回 undefined

注解:

因為最外層的fun 函數(shù)fun(n, o)是有2個參數(shù)的,如果第二個參數(shù)沒有傳,那么默認(rèn)就會被轉(zhuǎn)換為 undefined,所以執(zhí)行之后輸出 undefined,因為 console.log 輸出的是o console.log(o);

然后最外層這個 fun 函數(shù)會返回一個新對象,對象里面有一個屬性,名為 fun,而這個fun 屬性的值是一個匿名函數(shù),它會返回fun(m, n);

function fun(n, o) { // ① 
  console.log(o);  // 這里首先輸出了  n 的值為undefined
  return { // ②  
    fun: function(m) { // ③ 
      return fun(m, n); // ④  
    }
  };
}
2. a.fun(1); // 返回 0

注解:

由于之前運行了var a = fun(0);,返回了一個對象,并且賦值給了變量a,所以 a 是可以訪問對象里面的屬性的,例如a.fun

a.fun(1);這里意思是:

訪問 a 對象的 fun 屬性,因為a 的 fun 屬性的值保存的是一個匿名函數(shù)③,所以要使用的話需要加上()

a.fun() 實際上調(diào)用的是 fun 屬性里面的匿名函數(shù),由于匿名函數(shù)返回的fun(m, n); 無法在當(dāng)前作用域找到(因為當(dāng)前作用域沒有這個定義這個函數(shù)),所以會往上找,找到了頂層的函數(shù)fun(n, o),這樣就會出現(xiàn)閉包的狀態(tài),頂層的fun 函數(shù)被內(nèi)層的 fun 函數(shù)引用,之前①的fun(0)的0被保存下來了,作為 n 參數(shù)的值。

a.fun(1)這里傳入了第一個參數(shù)1,所以就是 m=1,(因為③接收一個參數(shù))。

所以④的fun(m,n)就會是fun(1,0),所以輸出0

// 已經(jīng)執(zhí)行過一次var a = fun(0)

function fun(n, o) { // ① 
  console.log(o);
  return { // ② 
    fun: function(m) { // ③ m=1
      return fun(m, n); // ④ 不斷引用①,閉包生成,①的n 的值被保存為0
    }
  };
}

3. a.fun(2); // 返回 0

注解:

這里傳入一個參數(shù),參數(shù)的值為2,跟上面的a.fun(1);是一樣的流程執(zhí)行。

最終是 fun(2,0)執(zhí)行,那么輸出 o 就是0了

function fun(n, o) { // ① 
  console.log(o);
  return { // ② 
    fun: function(m) { // ③ 
      return fun(m, n); // ④ 
    }
  };
}
4. a.fun(3); // 返回 0

跟上面雷同,所以不做解釋了。

二、第二個例子的輸出結(jié)果分析
第二個例子其實是一個語句,只是進(jìn)行了鏈?zhǔn)秸{(diào)用,所以會有一些不一樣的處理。
1. 第一個返回 undefined
var b = fun(0) // 返回 undefined

注解:

第一個返回 undefined 毋容置疑了,所以不說。

2. 第二個返回 0
 fun(0).fun(1) // 返回 0

注解:

執(zhí)行fun(0)的時候返回了一個對象,對象里面有 fun 屬性,而這個 fun 屬性的值是一個匿名函數(shù),這個匿名函數(shù)會返回一個 fun 函數(shù)。

當(dāng)執(zhí)行完fun(0)后,再鏈?zhǔn)街苯訄?zhí)行.fun(1)的時候,它是會調(diào)用前者返回的對象里的 fun 屬性,并且傳入了1作為第一個參數(shù),即m=1,并且返回的 fun 函數(shù)跟前者形成閉包,會不斷引用前者,所以 n=0 也被保存下來了。

所以最終執(zhí)行的時候是fun(m, n)fun(1,0),所以返回0

3. 第三個返回1
fun(0).fun(1).fun(2)

注解:

執(zhí)行fun(0)的時候返回了一個對象,對象里面有 fun 屬性,而這個 fun 屬性的值是一個匿名函數(shù),這個匿名函數(shù)會返回一個 fun 函數(shù)。

當(dāng)執(zhí)行完fun(0)后,再鏈?zhǔn)街苯訄?zhí)行.fun(1)的時候,它是會調(diào)用前者返回的對象里的 fun 屬性,并且傳入了1作為第一個參數(shù),即m=1,并且返回的 fun 函數(shù)跟前者形成閉包,會不斷引用前者,所以 n=0 也被保存下來了。

當(dāng)再次鏈?zhǔn)街苯訄?zhí)行.fun(2)的時候,這里使用的閉包是.fun(1)返回的閉包,因為每次執(zhí)行 fun 函數(shù)都會返回一個新對象,而.fun(2)引用的是.fun(1),所以 n 的值被保留為1

.fun(2)返回的是fun(m, n),而這里會跟.fun(1)(即fun(1, o))形成閉包,所以1為 n 的值被保留。

需要注意的是,js 作用域鏈只要找到可以使用的,就會馬上停止向上搜索,所以.fun(2)找到.fun(1)就馬上停止向上搜索了,所以引用的是.fun(1)的值。

4. 第四個返回是2

跟第三個返回類似,所以不做解釋了。

第三個例子的輸出結(jié)果分析
// 這里已經(jīng)無需多說了,跟第二個例子類似。
var c = fun(0).fun(1); // 返回 undefined 和0
1. 第三個返回是1,第四個返回是1
c.fun(2); // 第三個返回 1
c.fun(3); // 第四個返回 1

注解:

基于第一個返回和第二個返回,n 已經(jīng)被賦值為1了。

然后這里雖然多次執(zhí)行了 fun 函數(shù),但是因為沒有再次形成閉包,n 的值沒有再次被改變,所以一直保持著1.

為了避免原文被吃掉,所以我這里保留了截圖,并且加了一篇解釋 js 閉包還不錯的文章作為參考使用。

大部分人都會做錯的經(jīng)典JS閉包面試題.pdf

JavaScript 的閉包原理與詳解 - CSDN博客.pdf

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/108345.html

相關(guān)文章

  • 一道面試題認(rèn)識函數(shù)柯里化

    摘要:函數(shù)柯里化在函數(shù)式編程中,函數(shù)是一等公民。函數(shù)柯里化的主要作用和特點就是參數(shù)復(fù)用提前返回和延遲執(zhí)行。可能在實際應(yīng)用場景中,很少使用函數(shù)柯里化的解決方案,但是了解認(rèn)識函數(shù)柯里化對自身的提升還是有幫助的。 最近在整理面試資源的時候,發(fā)現(xiàn)一道有意思的題目,所以就記錄下來。 題目 如何實現(xiàn) multi(2)(3)(4)=24? 首先來分析下這道題,實現(xiàn)一個 multi 函數(shù)并依次傳入?yún)?shù)執(zhí)行,...

    13651657101 評論0 收藏0
  • 一道面試題談?wù)労瘮?shù)柯里化(Currying)

    摘要:忍者秘籍一書中,對于柯里化的定義如下在一個函數(shù)中首先填充幾個參數(shù)然后再返回一個新函數(shù)的技術(shù)稱為柯里化。回到我們的題目本身,其實根據(jù)測試用例我們可以發(fā)現(xiàn),函數(shù)的要求就是接受單一函數(shù),例如但是與柯里化不同之處在于,柯里化返回的一個新函數(shù)。   歡迎大家再一次來到我的文章專欄:從面試題中我們能學(xué)到什么,各位同行小伙伴是否已經(jīng)開始了悠閑的春節(jié)假期呢?在這里提前祝大家雞年大吉吧~哈哈,之前有人說...

    cppprimer 評論0 收藏0
  • 前端--通用知識 - 收藏集 - 掘金

    摘要:閉包有多重前端知識點大百科全書前端掘金,,技巧使你的更加專業(yè)前端掘金一個幫你提升技巧的收藏集。 Vue全家桶實現(xiàn)還原豆瓣電影wap版 - 掘金用vue全家桶仿寫豆瓣電影wap版。 最近在公司項目中嘗試使用vue,但奈何自己初學(xué)水平有限,上了vue沒有上vuex,開發(fā)過程特別難受。 于是玩一玩本項目,算是對相關(guān)技術(shù)更加熟悉了。 原計劃仿寫完所有頁面,礙于豆瓣的接口API有限,實現(xiàn)頁面也有...

    王笑朝 評論0 收藏0
  • 一道面試題,到“我可能看了假源碼[2]

    摘要:函數(shù)是這樣子聲明的使用了系統(tǒng)自己的構(gòu)造函數(shù)來聲明,第一個參數(shù)是,函數(shù)體內(nèi)又。構(gòu)造函數(shù)調(diào)用情況正常方式調(diào)用無窮無盡當(dāng)然,里還歸納了幾項比較簡單,我就不再翻譯了。 上一篇從一道面試題,到我可能看了假源碼中,由淺入深介紹了關(guān)于一篇經(jīng)典面試題的解法。最后在皆大歡喜的結(jié)尾中,突生變化,懸念又起。這一篇,就是為了解開這個懸念。 如果你還沒有看過前傳,可以參看前情回顧: 回顧1. 題目是模擬實現(xiàn)ES...

    chanthuang 評論0 收藏0
  • 一道面試題,到“我可能看了假源碼”

    摘要:返回的綁定函數(shù)也能使用操作符創(chuàng)建對象這種行為就像把原函數(shù)當(dāng)成構(gòu)造器。同時,將第一個參數(shù)以外的其他參數(shù),作為提供給原函數(shù)的預(yù)設(shè)參數(shù),這也是基本的顆粒化基礎(chǔ)。 今天想談?wù)勔坏狼岸嗣嬖囶},我做面試官的時候經(jīng)常喜歡用它來考察面試者的基礎(chǔ)是否扎實,以及邏輯、思維能力和臨場表現(xiàn),題目是:模擬實現(xiàn)ES5中原生bind函數(shù)。也許這道題目已經(jīng)不再新鮮,部分讀者也會有思路來解答。社區(qū)上關(guān)于原生bind的研...

    Carson 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<