03-立即執行函式

自由的代价很贵發表於2024-07-04

01 立即執行函式的定義

立即執行函式有自己的作用域,因此可以防止全域性變數之間的汙染

02 應用場景

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button class="btn">按鈕1</button>
    <button class="btn">按鈕2</button>
    <button class="btn">按鈕3</button>
    <button class="btn">按鈕4</button>
    <script>
        // 獲取所有的按鈕監聽點選
        var btnEls = document.querySelectorAll(".btn")
        for (var i = 0; i < btnEls.length; i++) {
            var btn = btnEls[i]
            btn.onclick = function(){
                console.log(`按鈕${i+1}發生了點選`)
            }
        }
    </script>
</body>
</html>

這是要先理解程式碼的執行順序,程式碼從上到下依次執行,當把for迴圈執行完了以後,i已經變成4了,而且btn.onclick這個函式是沒有被執行的,因為函式要執行必須要被呼叫,上面的程式碼中是沒有呼叫這個函式的,這個函式只有點選了才會被呼叫,當我們點選的時候,因為for迴圈是沒有作用域的,那麼function就會去上層作用域中尋找,在這裡就是全域性了,i已經變成4了!這個問題在es5的時候是很不好解決的
用立即執行函式來解決

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button class="btn">按鈕1</button>
    <button class="btn">按鈕2</button>
    <button class="btn">按鈕3</button>
    <button class="btn">按鈕4</button>
    <script>
        // 獲取所有的按鈕監聽點選
        var btnEls = document.querySelectorAll(".btn")
        for (var i = 0; i < btnEls.length; i++) {
            var btn = btnEls[i]
            (function() {
                btn.onclick = function(){
                console.log(`按鈕${i+1}發生了點選`)
                }
            })()
        }
    </script>
</body>
</html>

這樣寫依然會有問題,雖然立即執行可以立即執行,但是立即執行函式是有自己的作用域的,所以這裡立即執行函式里面依然找不到i,最後還是找到了全域性的i
改寫如下(用引數的形式把i傳進去)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button class="btn">按鈕1</button>
    <button class="btn">按鈕2</button>
    <button class="btn">按鈕3</button>
    <button class="btn">按鈕4</button>
    <script>
        // 獲取所有的按鈕監聽點選
        var btnEls = document.querySelectorAll(".btn")
        for (var i = 0; i < btnEls.length; i++) {
            var btn = btnEls[i];
            (function(m) {
                btn.onclick = function(){
                console.log(`按鈕${m+1}發生了點選`)
                }
            })(i)
        }
    </script>
</body>
</html>

相關文章