ES6之前
- 因为if和for都没有块级作用域的概念
- 我们都必须借助于function的作用域来接决应用外面变量 的问题
- 下面分析几种没有作用域带来的结果
1、变量作用域:变量在什么范围内是可用.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
{
var name = 'why';
console.log(name);
}
console.log(name);
</script>
</body>
</html>
本来想输出一个why,另一个报错,但是var没有块级作用域,结果如下
2、没有块级作用域引起的问题:if的块级
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
var func;
if(true){
var name = 'why';
func = function () {
console.log(name);
}
// func();
}
name = 'kobe';
func();
console.log(name);
</script>
</body>
</html>
本来想输出一个why一个kobe,但是结果如下
3、没有块级作用域引起的问题:for的块级
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button>按扭1</button>
<button>按扭2</button>
<button>按扭3</button>
<button>按扭4</button>
<button>按扭5</button>
<script>
var btns = document.getElementsByTagName('button');
for(var i = 0; i < btns.length; i++){
btns[i].addEventListener('click',function () {
console.log('第' + i + '个按钮被点击了');
})
}
</script>
</body>
</html>
这样会出问题(出现了联动问题,都是第五个按钮被点击),具体结果看下面的动图
那么如何解决上面的问题呢
必须闭包,为什么闭包会解决问题:函数是一个作用域
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button>按扭1</button>
<button>按扭2</button>
<button>按扭3</button>
<button>按扭4</button>
<button>按扭5</button>
<script>
var btns = document.getElementsByTagName('button');
for(var i = 0; i < btns.length; i++){
//
(function (num) {
btns[i].addEventListener('click',function () {
console.log('第' + num + '个按钮被点击了');
})
})(i)
}
</script>
</body>
</html>
ES6引入了let,有if和for的块级作用域
只需要将var改成let就好了
- 上面的点击按钮使用闭包函数,可以改成如下代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button>按扭1</button>
<button>按扭2</button>
<button>按扭3</button>
<button>按扭4</button>
<button>按扭5</button>
<script>
const btns = document.getElementsByTagName('button');
for(let i = 0; i < btns.length; i++){
btns[i].addEventListener('click',function () {
console.log('第' + i + '个按钮被点击了');
})
}
</script>
</body>
</html>