閉包和作用域
我大前端全靠JavaScript吃飯,而閉包和作用域也是JavaScript中的核心,其實在開發過程中我們經常用到閉包,常見到我們自己都不知道自己用了。
- 啥是閉包?
- 閉包和作用域有啥關係
- 閉包的使用場景
- 寫一個閉包的例項
1 閉包的概念和原理真的不想說,有的詳解看的很暈,牽涉到js語法和執行環境,執行機制等,所以不談。
2 閉包和作用域肯定是會被同時談到的,一個變數(自由變數)到底取哪個值取決於它所能用到的作用域。
請看下面這個例子:
上面的寫法錯誤的原因是在點選的時候,i變數早就變成了10(或者你也可以這麼理解:對dom的事件操作是屬於非同步的,所以不用說肯定這時候同步的任務早就結束了,i都更新到10且停止更新)
SO! 用閉包來保護我們的 i 變數吧,請看下面的寫法:
上面的寫法ok,原因在於把每一次的i變數當作引數傳給 一個自調函式,而引數被當時的i賦值後存在於函式內部作用域,是受到保護的,
不管外面i 發生了什麼也不會變。
3 閉包的一個例項
場景:假如有這樣一個需求,點選一個收藏圖示(暫不考慮取消收藏邏輯),我們呼叫一個預先寫好的函式,這個函式會判斷某個使用者是否已經點選了,如果沒有點選就高亮收藏,如果點選過了就提示已經收藏。請看下面的程式碼。
上面例項中的定義的變數 _list 處在函式閉包中,屬於私有變數,初衷是不希望它被隨意的改變,只能通過使用者點選時候的判斷。
而 return 函式中使用到的 _list 是自由變數,它的值需要在本作用域查詢,如果沒有就去父級作用域查詢。而這一系列查詢就是 作用域鏈。
總結:閉包使得變數的許可權收到保護和收斂,減少被汙染的可能性。