js函数的特点

yaxin
  • 1.5k
<!DOCTYPE HTML>
<html lang="zh-CN">
<head>
	<meta charset="UTF-8">
	<title></title>
</head>
<body>
	<ul id="nav_ul">
		<li><a href="">1</a></li>
		<li><a href="">2</a></li>
		<li><a href="">3</a></li>
		<li><a href="">4</a></li>
	</ul>
<script type="text/javascript">
var a = document.getElementById("nav_ul").getElementsByTagName("a");
for (var i = 0; i < a.length; i++) {
	a[i].onclick = function() {
		alert(i);
	}
}
</script>
</body>
</html>

上面代码中,无论点击那个连接,都是提示4,这个可以理解,但是将onclick放入单独函数中却正常,如下

<!DOCTYPE HTML>
<html lang="zh-CN">
<head>
	<meta charset="UTF-8">
	<title></title>
</head>
<body>
	<ul id="nav_ul">
		<li><a href="">1</a></li>
		<li><a href="">2</a></li>
		<li><a href="">3</a></li>
		<li><a href="">4</a></li>
	</ul>
<script type="text/javascript">
var a = document.getElementById("nav_ul").getElementsByTagName("a");
for (var i = 0; i < a.length; i++) {
	yy(i);
}
function yy(i) {
	a[i].onclick = function() {
		alert(i);
	}
}
</script>
</body>
</html>

如上,点击连接正常,请问这是什么原因?是js的函数有什么特别之处吗?

回复
阅读 5.1k
7 个回答

都是闭包惹的祸啊,改下吧。

var a = document.getElementById("nav_ul").getElementsByTagName("a");
for (var i = 0; i < a.length; i++) {
        a[i].onclick = (function(_i) {
                       return function() {
                                  alert(_i);
                              };
        })(i);
}
roshanca
  • 773

这个问题我写的比较详细,可以在这篇文章的最后部分“循环中的闭包”章节找到答案。

你在点击的时候,循环已经执行完毕了,这个时候你的i始终是4了,你点击当然是4了,你可以对元素判断,循环比较元素就可以了.

lz可以写coffeescript的代码,然后生成js,对我这种js半吊子,又不想深究的人来说,生成的代码质量比自己写js高很多:

http://coffeescript.org/

这个问题在刚刚开始看PPK谈javascipt的时候就留意过。书里面提到的是JS的局部变量的作用域问题。也可以试试this,

for (var i = 0; i < a.length; i++) {
        a[i].onclick = function() {
                alert(this.innerText);
        }
}

1.是关包,请在onclick = function () {}的时候返回 return function () { alert( '123' );}

2.变量作用于,a变量在function外,它是全局变量。

宣传栏