前端面試之什么是閉包

當(dāng)一個(gè)前端程序員被問到什么是閉包,和一個(gè)人被問到什么是人有異曲同工之妙。
對(duì)于前者,一直在用閉包,卻很難用語言去描述它,又不能抖個(gè)機(jī)靈,我查了下什么是蘋果,維基百科說道:"蘋果,又稱柰或林檎,是蘋果樹(學(xué)名:Malus pumila)的果實(shí)"。

不過,這個(gè)問題引發(fā)的思考,卻讓我收獲頗豐


函數(shù)內(nèi)部與函數(shù)外部之間的關(guān)系就是閉包
當(dāng)你創(chuàng)建了一個(gè)函數(shù),就是創(chuàng)建了一個(gè)閉包

  <script>
    function able() {}
  </script>

能夠訪問上層作用域鏈?zhǔn)情]包的特性

    function able() {
      let i = 0,
        j = 12;
      function test() {
        console.log(i++);
        console.dir(arguments.callee);
      }
      function test1() {
        console.log(i++);
        console.dir(arguments.callee);
      }
      test();
      test1();
      console.log(i);
    }


最后i的值是2,并沒有j的值,因?yàn)榇鎯?chǔ)到了[[scrop]]中,所以不在當(dāng)前上下文也能夠正常執(zhí)行
返回一個(gè)函數(shù)

  <script>
    function able() {
      let i = 0,
        j = 12;
      return function () {
        console.log(i++);
        console.dir(arguments.callee);
      };
    }
    const test = able();
    const test2 = able();
    test1();//0
    test1();//1
    test2();//0
    test2();//1
  </script>

作為宏任務(wù)

  <script>
    window.onload = function () {
      for (let i = 0; i < 10; i++) {
        var a = document.createElement('a');
        a.innerHTML = i + '<br/>';
        a.onclick = function () {
          console.dir(arguments.callee);
          console.log(i++);
        };
        document.body.append(a);
      }
    };
  </script>

內(nèi)存泄漏是指不可達(dá)的內(nèi)存無法被釋放,跟閉包本身無關(guān),跟錯(cuò)誤的邏輯有關(guān)

基本類型依附在函數(shù)內(nèi)部,存在棧中,當(dāng)函數(shù)出棧后立即被銷毀,當(dāng)訪問了上層作用域鏈,就會(huì)通過[[scope]]進(jìn)行記錄,形成了一個(gè)新的作用域鏈,會(huì)增大內(nèi)存,這并不代表著就一直存在內(nèi)存當(dāng)中

幾乎不需要手動(dòng)設(shè)置為null,除非和全局概念的東西綁定在一起,比如你不想讓果子掉在地上,把果子和樹枝綁定在一起,那所在的大樹杈斷了,照樣會(huì)掉在地上。

可以用來合理劃分變量層級(jí),狀態(tài)共享,實(shí)現(xiàn)私有變量,對(duì)外提供函數(shù)屏蔽內(nèi)部細(xì)節(jié),脫離執(zhí)行上下文訪問內(nèi)部變量,實(shí)現(xiàn)柯里化減少不必要的傳遞。

日常開發(fā)中我們更應(yīng)該去關(guān)心閉包對(duì)程序的可讀性、可維護(hù)性的影響,例如,不合理的使用閉包特性,導(dǎo)致對(duì)數(shù)據(jù)的操作邏輯零散在各個(gè)部分。

大文件上傳與閉包

2020 - 03 - 19
假設(shè)有一個(gè)超大的文件,一次性上傳接口容易延遲,因此在前端進(jìn)行分段上傳,有一個(gè)upload方法統(tǒng)一處理,大概就是轉(zhuǎn)為Blob對(duì)象,截取分段,創(chuàng)建ajax對(duì)象上傳,如果還有,再截取分段,創(chuàng)建ajax對(duì)象上傳。

用戶可以重新上傳,那如何終止上一次的上傳呢?

重新上傳會(huì)再次調(diào)用upload方法,這與前一個(gè)upload方法的"內(nèi)部生態(tài)"完全不同,相當(dāng)于開辟了一塊新內(nèi)存,但是他們卻必然有相同的"外部作用域"

所有我們可以在調(diào)用upload方法時(shí)傳一個(gè)時(shí)間戳,在內(nèi)部就通過形參保存就好,在進(jìn)行下一次分端上傳之前,判斷時(shí)間戳和外面的一樣就繼續(xù)上傳,不一樣就停止,因?yàn)樵俅握{(diào)用upload方法,外面的時(shí)間戳也會(huì)更新。

本文將持續(xù)更新

關(guān)注專題 前端便利店 http://www.itdecent.cn/c/c3f77a86d9a5 ,幫您省時(shí)省力!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容