跳至主要內容

变量作用域

chanchaw大约 1 分钟javascript

var全局变量在循环中的影响

下面代码中使用 var 定义的全局变量会导致所有按钮被赋予后最后一个点击事件

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>演示var作用域与闭包</title>
</head>
<body>
<button>按钮一</button>
<button>按钮二</button>
<button>按钮三</button>

</body>
<script type="text/javascript">
	var btns = document.getElementsByTagName('button');
	// 貌似根据不同按钮 index 打印不同的文案
	// 实际点击任何一个按钮最终都是打印 default 下的文案
	// 因为 var 作用域问题
	for(var i=0;i<btns.length;i++){
		btns[i].addEventListener('click',function(){
			switch(i){
				case 0:
					console.log('我是按钮一' + i);
					break;
				case 1:
					console.log('我是按钮二' + i);
					break;
				case 2:
					console.log('我是按钮三' + i);
					break;
				default:
					console.log('我是default' + i);
			}
		})
	}
</script>
</html>

要避免上面的问题可以将 var 替换为 let 或者 const,在 ES6 之前通过闭包解决该问题:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>演示var作用域与闭包</title>
</head>
<body>
<button>按钮一</button>
<button>按钮二</button>
<button>按钮三</button>

</body>
<script type="text/javascript">
	var btns = document.getElementsByTagName('button');
	// 貌似根据不同按钮 index 打印不同的文案
	// 实际点击任何一个按钮最终都是打印 default 下的文案
	// 因为 var 作用域问题
	for(var i=0;i<btns.length;i++){

		(function(i){

			btns[i].addEventListener('click',function(){
				switch(i){
					case 0:
						console.log('我是按钮一' + i);
						break;
					case 1:
						console.log('我是按钮二' + i);
						break;
					case 2:
						console.log('我是按钮三' + i);
						break;
					default:
						console.log('我是default' + i);
				}
			})

		})(i);// 闭包通过这里将外部变量传递进入内部
	}
</script>
</html>