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>