淺談閉包和非同步

westlife發表於2017-12-25

把複雜的知識簡單化------------------------------------------westlife

引言-----你知道嫦娥為什麼那麼善變嗎??? 因為chang er啊,哈哈哈哈!

縱觀js,有三座大山,這三座大山分別為--- 作用域/閉包 , 原型,  非同步和單執行緒.難倒了一代又一代前端小白,小白髮揮著愚公移山的精神,撓碎多少頭髮。傷害了多少神經元。。。。。

今天我來說下我所理解的閉包。

首先閉包產生地條件:有兩個。

1.函式巢狀函式

2.變數在外面那個函式宣告,在裡面呢個函式呼叫。

給大家看一個例子

function foo(){
    var a  = 10;
    return function(){
       return ++a
    }
}
var c = foo();
console.log(c());
console.log(c());複製程式碼

這就是一個簡單的閉包,在瀏覽器偵錯程式下可以看到分別列印了 11 12;

(ps:謝謝熱心網友的矯正,錯誤已經改回來)

那麼閉包有什麼作用呢?

作用1:儲存即將要被銷燬的資料

舉個小栗子:

大家記得做tab選項卡是怎麼做的嗎?恩,對,應該很多人都會做,無非就是找按鈕的下標,找內容區域的下標,一一對應,for迴圈遍歷按鈕,點選按鈕時,有事件了,所以產生了非同步,for迴圈的i值不能對應到點選事件的i值,這裡我們取巧了,給每個按鈕都新增了下標,對應下標的內容區域顯示出來,可是,存在一個問題,我們要在按鈕組新增一個變數為index,如果我們不想要這個index,我們能不能用其他方法實現呢,答案是我們能,可以用es6的塊級作用域來實現,當然我們也可以用閉包來實現

如圖:通常實現tab選項卡的方法淺談閉包和非同步

利用閉包來實現

(function(){
    var wrap = document.querySelector('#wrap');
    var pic = document.querySelector('#wrap');
    var aBtn = wrap.getElementsByTagName('li'); //獲取所有li組
    var aPic = pic.getElementsByTagName('div'); //獲取所有div組
    for(var i = 0;i<aBtn.length;i++){
       !function(n){
             aBtn[n].onclick = function(){
             aBtn[n].style.display = 'block'
            }
        }(i)
    }
}()複製程式碼

是不是很神奇,就用了一個變數i。本來變數i   for迴圈了就變成9(因為事件會產生非同步);嘿嘿嘿嘿....利用閉包,巧妙了實現了i值得再次利用

作用2:保密

demo:寫一段js程式碼,實現模擬汽車駕駛證科目一考試,做完一題,顯示出答案的效果

想必大家思路是有的,把答案全放進一個陣列裡,陣列的長度和題目的長度一樣,陣列了存放正確答案,當使用者點選按鈕時,在旁邊顯示的出此時此刻這個題目的答案,但是這樣資料不安全啊,稍微懂點程式碼的人在控制檯輸出答案;怎麼做到資料的保密性呢,--閉包

!function(){
var aBtn = document.getElementsByClassName('btn');//獲取所有按鈕
var arr = ["A","B","C","A"...........]  //存放答案數

for(var i = 0;i<aBtn.length;i++){
   !function(n){
        aBtn[n].onclick = function(){
            console.log("正確答案是:"+arr[n])
        }
    }()
}複製程式碼

就這樣寫出來了。利用匿名函式/立執行函式,資料不外洩,保密妥妥的,

其實說白了,閉包只是一種垃圾回收機制,有點像我們電腦中的回收站一樣。變數宣告要被銷燬時,利用閉包可以收集即將被銷燬的資料。

然後說下非同步:上文也提及到了非同步;我們的js程式碼是單執行緒執行的,從上到下執行;但是非同步時候出現時。非同步的執行程式碼會讓同步的執行程式碼有限通過;就好比紅綠燈一樣,等紅燈過去了我們才能通過,非同步就是這樣,等同步的程式碼執行完了才會通過,所以,同步總是優先於非同步!

觸發非同步的條件

  1. ajax
  2. 事件
  3. setTimeout() setInterval()
非同步就將這麼多,想聽後續如何,請聽下回分解!
                                                                  ___以上均為本人原創,如有紕漏,望能矯正。



相關文章