<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      由于最近在學(xué)習(xí)關(guān)于閉包相關(guān)的知識,并且閉包這個(gè)知識點(diǎn)讓我有點(diǎn)搞不太清楚其具體的定義,所以在網(wǎng)上也查閱了很多大佬的講解和對閉包的一個(gè)定義。

      ?

      最后感覺還是MDN上的說法感覺比較好理解一些,對閉包還是不太理解的道友可以嘗試看一看。

      MDN上是這樣說的:閉包是函數(shù)和聲明該函數(shù)的詞法環(huán)境的組合

      原地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
      <https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures>

      ?

      在了解閉包的過程中遇到一個(gè)很多地方都出現(xiàn)的一個(gè)面試題,按照自己的想法想了下發(fā)現(xiàn)幾乎沒對...所以就花了些時(shí)間分析了一下,供自己以后忘記了可以回顧一下。

      同時(shí),如果這里依舊存在一些誤區(qū),希望各位大佬們在評論區(qū)幫忙指正,感激萬分!

      ?

      原題如下:
      function fun(n, o) { console.log(o); return { fun: function (m) { return
      fun(m, n); } }; }var a = fun(0); // ? a.fun(1); // ? a.fun(2); // ? a.fun(3); //
      ? var b = fun(0).fun(1).fun(2).fun(3); // ? var c = fun(0).fun(1); // ?
      c.fun(2);// ? c.fun(3); // ?
      有興趣的道友們也可以試著先想一想答案,看下是否一致?

      ?

      以下是解題思路:

      1. 首先我對這個(gè)題畫了下題目中兩個(gè)fun函數(shù)中的一些信息 (可能不太完整,但是解題應(yīng)該夠用了)



      2. 當(dāng)執(zhí)行 var a = fun(0);
      時(shí),內(nèi)存中開辟了一塊新的空間給這個(gè)新的對象,這個(gè)對象中定義了一個(gè)方法fun。并且在fun(0)執(zhí)行時(shí),在當(dāng)前作用域下的變量信息如下:



      ?

      因此,當(dāng)該語句執(zhí)行時(shí),控制臺打印的值為 undefined

      ?

      3. 當(dāng)執(zhí)行 a.fun(1) 時(shí),因?yàn)閷ο骯中的fun方法在定義時(shí)所處的環(huán)境( [[scope]] )中存在一個(gè)變量n和變量o,

      并且在這條語句執(zhí)行的時(shí)候,變量n( 此時(shí)n的值為0 ) 被第三方
      (除了函數(shù)fun和方法fun)引用了,也就是被外部的對象a引用了,因此產(chǎn)生了Closure(閉包)。

      然后,這條語句的return執(zhí)行的時(shí)候先執(zhí)行 調(diào)用fun函數(shù)----> 把m的值傳遞給了fun函數(shù)中的n,把n傳遞給了fun函數(shù)中的o,
      因此控制臺中打印o的結(jié)果為0。

      然而事情并沒有結(jié)束,調(diào)用fun函數(shù)會返回一個(gè)新的對象,這個(gè)對象也會在內(nèi)存中新開辟一個(gè)空間,而
      此時(shí)這個(gè)新對象中的方法fun被定義時(shí)所處環(huán)境中的變量n已經(jīng)被賦值為m的值,也就是1了。



      4. 當(dāng)a.fun(2)執(zhí)行的時(shí)候,發(fā)生了和上面一樣的故事,并且內(nèi)存中又被返回了一個(gè)新的對象且
      這個(gè)新對象中的方法fun被定義時(shí)所處環(huán)境中的變量n已經(jīng)被賦值為m的值,也就是2

      5. a.fun(3)執(zhí)行同上,且這個(gè)新對象中的方法fun被定義時(shí)所處環(huán)境中的變量n已經(jīng)被賦值為m的值,也就是3

      故: a.fun(2) 和 a.fun(3)
      在控制臺中打印o的結(jié)果都為0,且不管你傳的參數(shù)是多少,只要你沒有改變a對象的值,那么輸出的結(jié)果都是0,因?yàn)槟銈鞯膮?shù)都存在新的對象中了。

      ?

      當(dāng)時(shí)我這里存在一個(gè)疑問,每次執(zhí)行n的值不是都被修改了嗎,為什么結(jié)果都是0呢?


      注意:因?yàn)槟闶冀K都是在調(diào)用a的方法,而你每次執(zhí)行a的方法fun的時(shí)候又沒有把新返回的對象重新賦值給a,所以a里面的fun方法被定義時(shí)所處環(huán)境中的變量n一直都是0

      ?

      6. 當(dāng)?var b = fun(0).fun(1).fun(2).fun(3); 執(zhí)行的時(shí)候就和上面疑問中的情形是一樣的了。

      當(dāng) fun(0)執(zhí)行的時(shí)候,同上面a.fun(0)一樣,返回結(jié)果是undefined,且此時(shí)產(chǎn)生的新對象中,方法fun被定義時(shí)所處環(huán)境中的變量n為0

      當(dāng) fun(1)執(zhí)行的時(shí)候,相當(dāng)于上面的a.fun(1)一樣,都是輸出0 (此時(shí)fun方法所處環(huán)境中的n為0),且返回一個(gè)新對象,新對象中的變量n為1

      當(dāng)fun(2)執(zhí)行的時(shí)候,就不太一樣了,因?yàn)槭窃谇耙粭l語句執(zhí)行結(jié)果后面直接調(diào)用fun方法,
      但此時(shí)的fun方法已經(jīng)不再是fun(1)中的方法了,而是上面返回的新對象中的方法,也就是變量n為1的方法,
      所以,這里輸出的結(jié)果為1,且返回一個(gè)新對象,新對象中的變量n為2

      當(dāng)fun(3)執(zhí)行的時(shí)候,和fun(2)的情況一樣,輸出結(jié)果為新的對象中的n,也就是2

      ?

      7. 到這里,var c = fun(0).fun(1); 應(yīng)該就能夠明白為什么這里輸出對的結(jié)果是 undefined 和 0 了

      因?yàn)榈览砗颓懊嬉粯?,第一個(gè) fun(0) 給n傳遞了值,但是o沒有,所以打印o的結(jié)果為undefined,第二個(gè) fun(1) 將n的值傳給了o,
      所以打印的結(jié)果為0,且這里產(chǎn)生的對象被賦值給了變量c,此時(shí)方法fun被定義時(shí)的環(huán)境(也就是它的詞法作用域)中的n是被重新賦值的1
      (方法fun的形參m把被傳過來的實(shí)參1,傳遞給了函數(shù)fun中的形參n)

      故:c.fun(2) 和 c.fun(3)中c對象的fun方法被定義時(shí)的環(huán)境中的n都是1,所以輸出的結(jié)果也是把n的值傳遞給fun函數(shù)中的o, 即輸出1

      ?

      此處是測試結(jié)果圖:


      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          国产精品久久久九九Av免费看 | 岳乱妇乱第13集 | 久久 无码 一区二区三区四区 | 免费高清在线观看黄网站 | 91精品国产91久久 | yin娃sao货调教情趣用品店 | 无遮挡边摸边吃奶边做视频免费 | 操香蕉| 国产精品天天爽视频 | 美女操bb |