从一个基础Javascript面试题谈起

记得第一次面试前端工程师的时候,面试官出了一个机试题,要求每个p单击时弹出不同的值,我是这么写的,执行的时候发现每次都是alert(5),当时坚持认为我的代码没有任何问题,心想这么简单的功能我怎么会弄错。时至今日,想起这件事,便写篇博文总结之。

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>面试试题</title>
<script type="text/javascript"> 
function init() {    
    var pArr = document.getElementsByTagName("p");    
    for( var i=0; i<pArr.length; i++ ) {    
         pArr[i].onclick = function() {    
         alert(i);    
    } 
  }
}
</script> 
</head> 
<body onload="init();"> 
<p>段落1</p> 
<p>断落</p> 
<p>段落3</p> 
<p>段落4</p> 
<p>段落5</p> 
</body> 
</html> 

执行以上的代码,会发现一个有趣的现象,每次单击p时弹出的结果都是5,究竟为什么呢,而不是0,1,2,3,4?我想发表一下个人见解:

以上代码是在onload的时候执行了init方法,即已经为每个P添加了单击事件监听,当我们单击P时,其实i的值此时已经是5了(这其实是一个程序执行的时间问题,在我们单击P之前,循环已经执行完毕,i的值最后变成了5退出了循环,如果我们可以做到在一个p添加单击时间之后和下一个p添加单击事件之前单击p的话,肯定得到的是0,1,2,3,4这样的结果,但是我们的速度不可能超过程序执行的速度,所以循环执行完后,i其实最后是5了,我们以后的单击都会alert(5),不知各位看官理解了没有)。

如果我们想每次单击都alert不同的值,我们可以参考下面这个简单可行的方法:

function init() {    
    var pArr = document.getElementsByTagName("p");    
    for( var i=0; i<pArr.length; i++ ) {    
         pArr[i].i=i;
         pArr[i].onclick = function() {    
         alert(this.i);    
    } 
  }
}

我们可以在循环添加单击事件时,将i的值存放到p里面(因为p是一个DOM对象,既然是对象,就可以添加属性和方法,这里我们为p添加一个属性i,赋值为i),最后我们每次单击p的时候alert的总是p[i]的属性值。

原文地址:https://www.cnblogs.com/iRavior/p/2793894.html