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>