作用域链

作用域链 《javascript DOM高级程序设计》 P35页

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<script type="text/javascript" src="ADS-start.js"></script>
<script type="text/javascript">
function initAnchors(){
	for(var i=1;i<=3;i++){
		var anchor = document.getElementById('anchor'+i);
		ADS.addEvent(anchor,'click',function(){
				alert('my id is anchor '+i);
			});
	}	
}

ADS.addEvent(window,'load',initAnchors);
</script>
</head>

<body>
<ul>
	<li><a href="" id="anchor1">anchor1</a></li>
	<li><a href="" id="anchor2">anchor2</a></li>
	<li><a href="" id="anchor3">anchor3</a></li>
</ul>

</body>
</html>

 点击后都会弹出''my id is anchor 4'

 

我们想要的结果是我们点击第几个出现的就是相关的数字,'my id is anchor 1',为什么会这样呢?因为不的值实际上是在单击事件发生时才从作用域链中取得的,当单击事件发生时,initAnchors()已经执行完毕,因此i的值等于4,所以每个alert都会显示相同的信息。具体来说,当click事件侦听器被调用并在它的内部作用域中查找i的值时,结果没有找到,因为i的值在作用click事件侦听器的匿名函数中没有定义。

     要得到正确的结果,需要把事件侦听器的注册转移到一个独立的函数中,并通过该函数的参数传递适当的值

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<script type="text/javascript" src="ADS-start.js"></script>
<script type="text/javascript">
function registerListener(anchor,i){
	ADS.addEvent(anchor,'click',function(){	
			
			alert('my id is anchor '+i);
		});	
}

function initAnchors(){
	for(var i=1;i<=3;i++){
		var anchor = document.getElementById('anchor'+i);
		
		registerListener(anchor,i);
	}	
}

ADS.addEvent(window,'load',initAnchors);
</script>
</head>

<body>
<ul>
	<li><a href="" id="anchor1">anchor1</a></li>
	<li><a href="" id="anchor2">anchor2</a></li>
	<li><a href="" id="anchor3">anchor3</a></li>
</ul>

</body>
</html>

  由于在作用域链中定义了额外的函数和变量,提示信息中保持了正确的值。因为click事件侦听器现在的外部使用域变成了

registerListener()函数,该函数在其每个实例(每次调用registerListener()函数都会生成该函数的一个副本,以维护正确的变量作用域)的内部作用域中都为i维护了一个唯一值。

 

你可能感兴趣的:(作用域)